Added DTMF playback and another fall back if DTMF fails to send. Fixed problem with MGMXML leaking. Added phone number to name field if there is a name for the inbox. Rewrote the map display system fo be more compact. Fixed issue with the possibility of a phone call being automatically answered after you placed a call using Google Voice and SIP. Changed the ring sound to use MGMSound instead of NSSound for compatibility with iPhone and bug fixes. Added the ability to see who you are calling if your using Google Voice to SIP calling. Made the clear button on the phone field hide when the string is blank.

This commit is contained in:
GRMrGecko 2010-10-12 00:53:17 -05:00
parent 5dc36cc158
commit a644448ef9
23 changed files with 279 additions and 308 deletions

View File

@ -22,7 +22,7 @@
- (NSString *)replace:(NSString *)targetString with:(NSString *)replaceString;
- (BOOL)containsString:(NSString *)string;
- (NSString *)escapeSMS;
- (NSString *)javascriptEscape;
- (NSString *)filePath;
- (NSString *)littersToNumbers;

View File

@ -67,7 +67,7 @@
return ([[self lowercaseString] rangeOfString:[string lowercaseString]].location != NSNotFound);
}
- (NSString *)escapeSMS {
- (NSString *)javascriptEscape {
NSString *escaped = [self replace:@"\\" with:@"\\\\"];
escaped = [escaped replace:@"'" with:@"\\'"];
escaped = [escaped replace:@"\n" with:@"<br />"];

View File

@ -85,7 +85,7 @@
}
- (void)play {
[sound play];
[sound performSelectorOnMainThread:@selector(play) withObject:nil waitUntilDone:NO];
}
- (void)pause {
[sound pause];

View File

@ -90,6 +90,7 @@ typedef enum {
pj_pool_t *PJPool;
int port;
pjsua_media_config mediaConfig;
pjmedia_port *ringbackPort;
pjsua_conf_port_id ringbackSlot;
pjsua_transport_id UDPTransport;
@ -126,6 +127,7 @@ typedef enum {
- (pj_pool_t *)PJPool;
- (int)port;
- (void)setPort:(int)thePort;
- (pjsua_media_config)mediaConfig;
- (pjmedia_port *)ringbackPort;
- (pjsua_conf_port_id)ringbackSlot;
- (MGMSIPNATType)NATType;

View File

@ -208,6 +208,14 @@ static void MGMSIPDetectedNAT(const pj_stun_nat_detect_result *result) {
[pool drain];
}
static void MGMSIPDTMFReceived(pjsua_call_id callIdentifier, int dtmfDigit) {
NSAutoreleasePool *pool = [NSAutoreleasePool new];
MGMSIPCall *call = [[MGMSIP sharedSIP] callWithIdentifier:callIdentifier];
[call receivedDTMFDigit:dtmfDigit];
PJ_LOG(3, (THIS_FILE, "Received DTMF on call %d: %c", callIdentifier, dtmfDigit));
[pool drain];
}
#if !TARGET_OS_IPHONE
static void MGMNetworkNotification(SCDynamicStoreRef store, NSArray *changedKeys, void *info) {
for (int i=0; i<[changedKeys count]; ++i) {
@ -251,8 +259,10 @@ static OSStatus MGMAudioDevicesChanged(AudioHardwarePropertyID propertyID, void
state = MGMSIPStoppedState;
NATType = MGMSIPNATUnknownType;
accounts = [NSMutableArray new];
#if !TARGET_OS_IPHONE
lastInputDevice = -1;
lastOutputDevice = -1;
#endif
shouldRestart = NO;
#if !TARGET_OS_IPHONE
@ -332,6 +342,9 @@ static OSStatus MGMAudioDevicesChanged(AudioHardwarePropertyID propertyID, void
- (void)setPort:(int)thePort {
port = thePort;
}
- (pjsua_media_config)mediaConfig {
return mediaConfig;
}
- (pjmedia_port *)ringbackPort {
return ringbackPort;
}
@ -383,7 +396,6 @@ static OSStatus MGMAudioDevicesChanged(AudioHardwarePropertyID propertyID, void
loggingConfig.level = [defaults integerForKey:MGMSIPLogLevel];
loggingConfig.console_level = [defaults integerForKey:MGMSIPConsoleLogLevel];
pjsua_media_config mediaConfig;
pjsua_media_config_default(&mediaConfig);
mediaConfig.no_vad = ![defaults boolForKey:MGMSIPVoiceActivityDetection];
mediaConfig.enable_ice = [defaults boolForKey:MGMSIPInteractiveConnectivityEstablishment];
@ -402,6 +414,7 @@ static OSStatus MGMAudioDevicesChanged(AudioHardwarePropertyID propertyID, void
sipConfig.cb.on_call_transfer_status = &MGMSIPCallTransferStatusChanged;
sipConfig.cb.on_reg_state = &MGMSIPAccountRegistrationStateChanged;
sipConfig.cb.on_nat_detect = &MGMSIPDetectedNAT;
sipConfig.cb.on_dtmf_digit = &MGMSIPDTMFReceived;
sipConfig.max_calls = MGMSIPMaxCalls;

View File

@ -28,6 +28,7 @@
- (void)localPlacedHold:(MGMSIPCall *)theCall;
- (void)remotePlacedHold:(MGMSIPCall *)theCall;
- (void)transferStatusCahgned:(MGMSIPCall *)theCall;
- (void)receivedDMTFDigit:(int)theDigit;
@end
typedef enum {
@ -61,6 +62,9 @@ typedef enum {
pjsua_player_id holdMusicPlayer;
pjsua_recorder_id recorderID;
pjmedia_port *toneGenPort;
pjsua_conf_port_id toneGenSlot;
BOOL isRingbackOn;
}
- (id)initWithIdentifier:(int)theIdentifier account:(MGMSIPAccount *)theAccount;
@ -108,6 +112,7 @@ typedef enum {
- (void)stopRingback;
- (void)sendDTMFDigits:(NSString *)theDigits;
- (void)receivedDTMFDigit:(int)theDigit;
- (void)playSound:(NSString *)theFile;
- (pjsua_player_id)playSoundMain:(NSString *)theFile loop:(BOOL)shouldLoop;

View File

@ -40,6 +40,19 @@
incoming = (state==MGMSIPCallIncomingState);
muted = NO;
pjsua_media_config mediaConfig = [[MGMSIP sharedSIP] mediaConfig];
unsigned int samplesPerFrame = mediaConfig.audio_frame_ptime * mediaConfig.clock_rate * mediaConfig.channel_count / 1000;
pj_status_t status = pjmedia_tonegen_create([[MGMSIP sharedSIP] PJPool], mediaConfig.clock_rate, mediaConfig.channel_count, samplesPerFrame, 16, 0, &toneGenPort);
if (status!=PJ_SUCCESS) {
NSLog(@"Error creating tone generator");
} else {
status = pjsua_conf_add_port([[MGMSIP sharedSIP] PJPool], toneGenPort, &toneGenSlot);
if (status!=PJ_SUCCESS)
NSLog(@"Error adding tone generator");
else
pjsua_conf_connect(toneGenSlot, 0);
}
}
bzero(&PJThreadDesc, sizeof(pj_thread_desc));
}
@ -61,6 +74,11 @@
[transferStatusText release];
if (holdMusicPath!=nil)
[holdMusicPath release];
if (toneGenPort!=NULL) {
pjsua_conf_remove_port(toneGenSlot);
pjmedia_port_destroy(toneGenPort);
toneGenPort = NULL;
}
[super dealloc];
}
@ -318,12 +336,15 @@
if (identifier==PJSUA_INVALID_ID || state!=MGMSIPCallConfirmedState)
return;
BOOL sendSuccessful = NO;
pj_thread_desc PJThreadDesc;
[[MGMSIP sharedSIP] registerThread:&PJThreadDesc];
pj_str_t digits = [theDigits PJString];
pj_status_t status = pjsua_call_dial_dtmf(identifier, &digits);
if (status!=PJ_SUCCESS) {
sendSuccessful = (status==PJ_SUCCESS);
if (!sendSuccessful) {
const pj_str_t INFO = pj_str("INFO");
for (unsigned int i=0; i<[theDigits length]; i++) {
pjsua_msg_data messageData;
@ -332,10 +353,46 @@
messageData.msg_body = [[NSString stringWithFormat:@"Signal=%C\r\nDuration=300", [theDigits characterAtIndex:i]] PJString];
status = pjsua_call_send_request(identifier, &INFO, &messageData);
if (status!=PJ_SUCCESS)
NSLog(@"Unable to send DTMF with status %d.", status);
sendSuccessful = (status==PJ_SUCCESS);
}
}
if (!sendSuccessful)
pjsua_conf_connect(toneGenSlot, pjsua_call_get_conf_port(identifier));
for (unsigned int i=0; i<[theDigits length]; i++) {
pjmedia_tonegen_stop(toneGenPort);
pjmedia_tone_digit digit[1];
digit[0].digit = [theDigits characterAtIndex:i];
digit[0].on_msec = 100;
digit[0].off_msec = 100;
digit[0].volume = 16383;
pjmedia_tonegen_play_digits(toneGenPort, 1, digit, 0);
if ([theDigits length]!=1 && (i+1)<[theDigits length]) [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]];
}
if (!sendSuccessful)
pjsua_conf_disconnect(toneGenSlot, pjsua_call_get_conf_port(identifier));
bzero(&PJThreadDesc, sizeof(pj_thread_desc));
}
- (void)receivedDTMFDigit:(int)theDigit {
if (identifier==PJSUA_INVALID_ID || state!=MGMSIPCallConfirmedState)
return;
if (delegate!=nil && [delegate respondsToSelector:@selector(receivedDMTFDigit:)]) [delegate receivedDMTFDigit:theDigit];
pj_thread_desc PJThreadDesc;
[[MGMSIP sharedSIP] registerThread:&PJThreadDesc];
pjmedia_tonegen_stop(toneGenPort);
pjmedia_tone_digit digit[1];
digit[0].digit = theDigit;
digit[0].on_msec = 100;
digit[0].off_msec = 100;
digit[0].volume = 16383;
pjmedia_tonegen_play_digits(toneGenPort, 1, digit, 0);
bzero(&PJThreadDesc, sizeof(pj_thread_desc));
}

View File

@ -12,6 +12,7 @@
@implementation MGMXMLElement
- (id)initWithXMLString:(NSString *)string error:(NSError **)error {
[super release];
MGMXMLDocument *document = [[MGMXMLDocument alloc] initWithXMLString:string options:0 error:error];
MGMXMLElement *element = nil;
if (document!=nil) {

View File

@ -69,9 +69,9 @@
}
- (void)request:(NSDictionary *)theInfo didFailWithError:(NSError *)theError {
NSLog(@"Starting Voicemail Error: %@", theError);
NSLog(@"Starting Audio Error: %@", theError);
NSAlert *theAlert = [[NSAlert new] autorelease];
[theAlert setMessageText:@"Error loading voicemail"];
[theAlert setMessageText:@"Error loading audio"];
[theAlert setInformativeText:[theError localizedDescription]];
[theAlert runModal];
}

View File

@ -371,7 +371,11 @@ NSString * const MGMSID = @"id";
if ([identifier isEqual:@"read"]) {
return ([[data objectForKey:MGMIRead] boolValue] ? @"" : @"•");
} else if ([identifier isEqual:@"name"]) {
return [[instance contacts] nameForNumber:[data objectForKey:MGMIPhoneNumber]];
NSString *name = [[instance contacts] nameForNumber:[data objectForKey:MGMIPhoneNumber]];
NSString *number = [[data objectForKey:MGMIPhoneNumber] readableNumber];
if ([name isEqual:number])
return number;
return [NSString stringWithFormat:@"%@ (%@)", name, number];
} else if ([identifier isEqual:@"text"]) {
int type = [[data objectForKey:MGMIType] intValue];
if (type==MGMIVoicemailType) {

View File

@ -297,9 +297,8 @@ NSString * const MGMLoading = @"Loading...";
}
query = [NSDictionary dictionaryWithDictionary:dataDic];
}*/
if ([data hasPrefix:@"//"]) {
if ([data hasPrefix:@"//"])
data = [data substringFromIndex:2];
}
if ([scheme isEqualToString:@"tel"] || [scheme isEqualToString:@"callto"] || [scheme isEqualToString:@"telephone"] || [scheme isEqualToString:@"phone"] || [scheme isEqualToString:@"phonenumber"]) {
if (currentContactsController==-1)
return;
@ -568,13 +567,20 @@ NSString * const MGMLoading = @"Loading...";
[RLPhoneNumber setStringValue:@""];
}
if ([theInfo objectForKey:MGMWPAddress]) {
[[RLMap windowScriptObject] callWebScriptMethod:@"showAddress" withArguments:[NSArray arrayWithObjects:[NSString stringWithFormat:@"%@, %@", [theInfo objectForKey:MGMWPAddress], [theInfo objectForKey:MGMWPZip]], [NSNumber numberWithInt:15], nil]];
} else if ([theInfo objectForKey:MGMWPZip]) {
[[RLMap windowScriptObject] callWebScriptMethod:@"showAddress" withArguments:[NSArray arrayWithObjects:[theInfo objectForKey:MGMWPZip], [NSNumber numberWithInt:13], nil]];
} else if ([theInfo objectForKey:MGMWPLocation]) {
[[RLMap windowScriptObject] callWebScriptMethod:@"showAddress" withArguments:[NSArray arrayWithObjects:[theInfo objectForKey:MGMWPLocation], [NSNumber numberWithInt:13], nil]];
int zoom = 0;
NSString *address = nil;
if ([theInfo objectForKey:MGMWPAddress]!=nil) {
address = [NSString stringWithFormat:@"%@, %@", [theInfo objectForKey:MGMWPAddress], [theInfo objectForKey:MGMWPZip]];
zoom = 15;
} else if ([theInfo objectForKey:MGMWPZip]!=nil) {
address = [theInfo objectForKey:MGMWPZip];
zoom = 13;
} else if ([theInfo objectForKey:MGMWPLocation]!=nil) {
address = [theInfo objectForKey:MGMWPLocation];
zoom = 13;
}
if (address!=nil)
[RLMap stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"showAddress('%@', %d);", [address javascriptEscape], zoom]];
}
- (IBAction)donate:(id)sender {

View File

@ -43,6 +43,7 @@ extern NSString *MGMLastUserPhoneKey;
- (void)setInstanceInfo;
- (BOOL)isPlacingCall;
- (void)donePlacingCall;
- (IBAction)sms:(id)sender;

View File

@ -200,6 +200,9 @@ NSString *MGMLastUserPhoneKey = @"MGMLastUserPhone";
- (BOOL)isPlacingCall {
return (callTimer!=nil);
}
- (void)donePlacingCall {
[callTimer fire];
}
- (IBAction)runAction:(id)sender {
if ([[user settingForKey:MGMSContactsActionKey] intValue]==0) {
[self call:sender];
@ -209,6 +212,7 @@ NSString *MGMLastUserPhoneKey = @"MGMLastUserPhone";
}
- (IBAction)call:(id)sender {
if (callTimer!=nil) {
placingCall = NO;
[callTimer invalidate];
[callTimer release];
callTimer = nil;
@ -265,17 +269,11 @@ NSString *MGMLastUserPhoneKey = @"MGMLastUserPhone";
}
- (IBAction)sms:(id)sender {
NSString *phoneNumber = nil;
if (![[phoneField stringValue] isPhoneComplete]) {
if ([contactViews count]>0) {
[self selectFirstContact];
} else {
return;
NSString *phoneNumber = [controller currentPhoneNumber];
if (phoneNumber==nil || [phoneNumber isEqual:@""]) {
NSBeep();
return;
}
}
if (phoneNumber==nil)
phoneNumber = [[phoneField stringValue] phoneFormatWithAreaCode:[instance userAreaCode]];
[[controller SMSManager] messageWithNumber:phoneNumber instance:instance];
}

View File

@ -9,7 +9,7 @@
#if MGMSIPENABLED
#import <Cocoa/Cocoa.h>
@class MGMSIPCall, MGMSIPAccount, MGMSIPUser, MGMWhitePages, QTMovie;
@class MGMSIPCall, MGMSIPAccount, MGMSIPUser, MGMWhitePages, MGMSound;
@interface MGMSIPCallWindow : NSObject {
MGMSIPCall *call;
@ -25,7 +25,7 @@
NSString *fullName;
NSString *phoneNumber;
NSSound *ringtone;
MGMSound *ringtone;
NSDate *startTime;
NSTimer *durationUpdater;
@ -85,17 +85,6 @@
- (IBAction)muteMicrophone:(id)sender;
- (IBAction)muteSpeakers:(id)sender;
- (IBAction)sound:(id)sender;
- (IBAction)n1:(id)sender;
- (IBAction)n2:(id)sender;
- (IBAction)n3:(id)sender;
- (IBAction)n4:(id)sender;
- (IBAction)n5:(id)sender;
- (IBAction)n6:(id)sender;
- (IBAction)n7:(id)sender;
- (IBAction)n8:(id)sender;
- (IBAction)n9:(id)sender;
- (IBAction)n0:(id)sender;
- (IBAction)nStar:(id)sender;
- (IBAction)nPound:(id)sender;
- (IBAction)dial:(id)sender;
@end
#endif

View File

@ -45,9 +45,11 @@ NSString * const MGMSCTitleNoNameFormat = @"Call With %@";
[incomingWindow setLevel:NSStatusWindowLevel];
[incomingWindow setExcludedFromWindowsMenu:YES];
BOOL autoAnswer = [SIPUser autoAnswer];
NSString *phoneCalling = [SIPUser phoneCalling];
if (phoneCalling!=nil)
[[call remoteURL] setUserName:phoneCalling];
if ([call isIncoming] && !autoAnswer) {
if ([call isIncoming] && phoneCalling==nil) {
if ([[[call remoteURL] userName] isPhone]) {
NSString *number = [[[call remoteURL] userName] phoneFormat];
phoneNumber = [[number readableNumber] copy];
@ -73,7 +75,12 @@ NSString * const MGMSCTitleNoNameFormat = @"Call With %@";
}
[incomingWindow makeKeyAndOrderFront:self];
[call sendRingingNotification];
[self performSelectorOnMainThread:@selector(startRingtone) withObject:nil waitUntilDone:NO];
NSString *ringtonePath = [[[SIPUser controller] themeManager] currentSoundPath:MGMTSSIPRingtone];
if (![ringtonePath isEqual:MGMTNoSound]) {
ringtone = [[MGMSound alloc] initWithContentsOfFile:ringtonePath];
[ringtone setLoops:YES];
[ringtone play];
}
} else {
if ([[[call remoteURL] userName] isPhone]) {
NSString *number = [[[call remoteURL] userName] phoneFormat];
@ -91,7 +98,7 @@ NSString * const MGMSCTitleNoNameFormat = @"Call With %@";
fullName = [[[call remoteURL] fullName] copy];
}
[self fillCallWindow];
if (autoAnswer)
if (phoneCalling!=nil)
[call answer];
[callWindow makeKeyAndOrderFront:self];
}
@ -134,20 +141,6 @@ NSString * const MGMSCTitleNoNameFormat = @"Call With %@";
[super dealloc];
}
- (void)startRingtone {
NSString *ringtonePath = [[[SIPUser controller] themeManager] currentSoundPath:MGMTSSIPRingtone];
if (![ringtonePath isEqual:MGMTNoSound]) {
ringtone = [[NSSound alloc] initWithContentsOfFile:ringtonePath byReference:YES];
[ringtone setDelegate:self];
[ringtone play];
}
}
- (void)sound:(NSSound *)sound didFinishPlaying:(BOOL)finishedPlaying {
if (finishedPlaying && sound==ringtone)
[ringtone play];
}
- (void)disconnected:(MGMSIPCall *)theCall {
if (ringtone!=nil) {
[ringtone stop];
@ -232,6 +225,7 @@ NSString * const MGMSCTitleNoNameFormat = @"Call With %@";
ringtone = nil;
}
[incomingWindow close];
[SIPUser callDone:self];
}
- (void)updateDuration {
@ -337,40 +331,30 @@ NSString * const MGMSCTitleNoNameFormat = @"Call With %@";
[call playSound:soundFile];
[[[SIPUser controller] themeManager] performSelector:@selector(playSound:) withObject:soundName afterDelay:0.2]; // The phone has a delay, so why not delay this so you hear it at the same time?
}
- (IBAction)n1:(id)sender {
- (IBAction)dial:(id)sender {
if (sender==n1Button)
[call sendDTMFDigits:@"1"];
}
- (IBAction)n2:(id)sender {
else if (sender==n2Button)
[call sendDTMFDigits:@"2"];
}
- (IBAction)n3:(id)sender {
else if (sender==n3Button)
[call sendDTMFDigits:@"3"];
}
- (IBAction)n4:(id)sender {
else if (sender==n4Button)
[call sendDTMFDigits:@"4"];
}
- (IBAction)n5:(id)sender {
else if (sender==n5Button)
[call sendDTMFDigits:@"5"];
}
- (IBAction)n6:(id)sender {
else if (sender==n6Button)
[call sendDTMFDigits:@"6"];
}
- (IBAction)n7:(id)sender {
else if (sender==n7Button)
[call sendDTMFDigits:@"7"];
}
- (IBAction)n8:(id)sender {
else if (sender==n8Button)
[call sendDTMFDigits:@"8"];
}
- (IBAction)n9:(id)sender {
else if (sender==n9Button)
[call sendDTMFDigits:@"9"];
}
- (IBAction)n0:(id)sender {
[call sendDTMFDigits:@"0"];
}
- (IBAction)nStar:(id)sender {
else if (sender==nStarButton)
[call sendDTMFDigits:@"*"];
}
- (IBAction)nPound:(id)sender {
else if (sender==n0Button)
[call sendDTMFDigits:@"0"];
else if (sender==nPoundButton)
[call sendDTMFDigits:@"#"];
}

View File

@ -41,7 +41,7 @@ extern NSString * const MGMSIPUserAreaCode;
- (void)removeLoginProgress;
- (void)loginErrored;
- (BOOL)autoAnswer;
- (NSString *)phoneCalling;
- (void)gotNewCall:(MGMSIPCall *)theCall;
- (void)callDone:(MGMSIPCallWindow *)theCall;
@end

View File

@ -190,7 +190,6 @@ NSString * const MGMSIPUserAreaCode = @"MGMVSIPUserAreaCode";
[theAlert setMessageText:@"Error logging out"];
[theAlert setInformativeText:[account lastError]];
[theAlert runModal];
}
- (void)animationDidEnd:(NSAnimation *)animation {
if (progressFadeAnimation!=nil) {
@ -229,12 +228,15 @@ NSString * const MGMSIPUserAreaCode = @"MGMVSIPUserAreaCode";
[account makeCallToNumber:phoneNumber];
}
- (BOOL)autoAnswer {
- (NSString *)phoneCalling {
for (int i=0; i<[[controller contactsControllers] count]; i++) {
if ([[[controller contactsControllers] objectAtIndex:i] isKindOfClass:[MGMVoiceUser class]] && [[[controller contactsControllers] objectAtIndex:i] isPlacingCall])
return YES;
if ([[[controller contactsControllers] objectAtIndex:i] isKindOfClass:[MGMVoiceUser class]] && [[[controller contactsControllers] objectAtIndex:i] isPlacingCall]) {
MGMVoiceUser *voiceUser = [[controller contactsControllers] objectAtIndex:i];
[voiceUser donePlacingCall];
return [voiceUser currentPhoneNumber];
}
return NO;
}
return nil;
}
- (void)gotNewCall:(MGMSIPCall *)theCall {
[calls addObject:[MGMSIPCallWindow windowWithCall:theCall SIPUser:self]];

View File

@ -179,7 +179,7 @@
}
NSDateFormatter *formatter = [[NSDateFormatter new] autorelease];
[formatter setDateFormat:[[[manager themeManager] variant] objectForKey:MGMTDate]];
[SMSView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"newMessage('%@', '%@', '%@', %@, '%@', '%@', '%@', %d);", [[message objectForKey:MGMIText] escapeSMS], [[message objectForKey:MGMTPhoto] escapeSMS], [[message objectForKey:MGMITime] escapeSMS], [message objectForKey:MGMIID], [[message objectForKey:MGMTName] escapeSMS], [[[message objectForKey:MGMIPhoneNumber] readableNumber] escapeSMS], [formatter stringFromDate:[messageInfo objectForKey:MGMITime]], type]];
[SMSView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"newMessage('%@', '%@', '%@', %@, '%@', '%@', '%@', %d);", [[message objectForKey:MGMIText] javascriptEscape], [[message objectForKey:MGMTPhoto] javascriptEscape], [[message objectForKey:MGMITime] javascriptEscape], [message objectForKey:MGMIID], [[message objectForKey:MGMTName] javascriptEscape], [[[message objectForKey:MGMIPhoneNumber] readableNumber] javascriptEscape], [formatter stringFromDate:[messageInfo objectForKey:MGMITime]], type]];
[SMSView stringByEvaluatingJavaScriptFromString:@"scrollToBottom();"];
}

View File

@ -159,6 +159,7 @@
- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView*)controlView {
[super drawWithFrame:cellFrame inView:controlView];
if ([[self stringValue] length]>0)
[clearButton drawWithFrame:[self clearButtonRectForBounds:cellFrame] inView:controlView];
}

View File

@ -12,9 +12,9 @@
</object>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool>
<integer value="201"/>
<integer value="15"/>
<integer value="3"/>
<integer value="201"/>
<integer value="16"/>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
@ -231,7 +231,7 @@
<object class="NSTextFieldCell" key="NSCell" id="1065347165">
<int key="NSCellFlags">68288064</int>
<int key="NSCellFlags2">4195328</int>
<string key="NSContents">00:00:00</string>
<string key="NSContents">0:00:00</string>
<object class="NSFont" key="NSSupport" id="779016805">
<string key="NSName">LucidaGrande</string>
<double key="NSSize">13</double>
@ -397,7 +397,7 @@
<object class="NSTextFieldCell" key="NSCell" id="16951803">
<int key="NSCellFlags">68288064</int>
<int key="NSCellFlags2">4195328</int>
<string key="NSContents">Status Message</string>
<string key="NSContents">Disconnected</string>
<reference key="NSSupport" ref="779016805"/>
<reference key="NSControlView" ref="717085855"/>
<reference key="NSBackgroundColor" ref="693930386"/>
@ -1230,102 +1230,6 @@
</object>
<int key="connectionID">224</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">n1:</string>
<reference key="source" ref="1001"/>
<reference key="destination" ref="698319772"/>
</object>
<int key="connectionID">230</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">n2:</string>
<reference key="source" ref="1001"/>
<reference key="destination" ref="758933209"/>
</object>
<int key="connectionID">231</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">n3:</string>
<reference key="source" ref="1001"/>
<reference key="destination" ref="811735183"/>
</object>
<int key="connectionID">232</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">n4:</string>
<reference key="source" ref="1001"/>
<reference key="destination" ref="181872348"/>
</object>
<int key="connectionID">233</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">n5:</string>
<reference key="source" ref="1001"/>
<reference key="destination" ref="432131395"/>
</object>
<int key="connectionID">234</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">n6:</string>
<reference key="source" ref="1001"/>
<reference key="destination" ref="65218013"/>
</object>
<int key="connectionID">235</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">n7:</string>
<reference key="source" ref="1001"/>
<reference key="destination" ref="798981467"/>
</object>
<int key="connectionID">236</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">n8:</string>
<reference key="source" ref="1001"/>
<reference key="destination" ref="819368832"/>
</object>
<int key="connectionID">237</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">n9:</string>
<reference key="source" ref="1001"/>
<reference key="destination" ref="693176110"/>
</object>
<int key="connectionID">238</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">nStar:</string>
<reference key="source" ref="1001"/>
<reference key="destination" ref="667173404"/>
</object>
<int key="connectionID">239</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">nPound:</string>
<reference key="source" ref="1001"/>
<reference key="destination" ref="92905949"/>
</object>
<int key="connectionID">240</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">n0:</string>
<reference key="source" ref="1001"/>
<reference key="destination" ref="632346904"/>
</object>
<int key="connectionID">241</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">showPadButton</string>
@ -1414,6 +1318,102 @@
</object>
<int key="connectionID">255</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">dial:</string>
<reference key="source" ref="1001"/>
<reference key="destination" ref="698319772"/>
</object>
<int key="connectionID">256</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">dial:</string>
<reference key="source" ref="1001"/>
<reference key="destination" ref="758933209"/>
</object>
<int key="connectionID">257</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">dial:</string>
<reference key="source" ref="1001"/>
<reference key="destination" ref="811735183"/>
</object>
<int key="connectionID">258</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">dial:</string>
<reference key="source" ref="1001"/>
<reference key="destination" ref="181872348"/>
</object>
<int key="connectionID">259</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">dial:</string>
<reference key="source" ref="1001"/>
<reference key="destination" ref="432131395"/>
</object>
<int key="connectionID">260</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">dial:</string>
<reference key="source" ref="1001"/>
<reference key="destination" ref="65218013"/>
</object>
<int key="connectionID">261</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">dial:</string>
<reference key="source" ref="1001"/>
<reference key="destination" ref="798981467"/>
</object>
<int key="connectionID">262</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">dial:</string>
<reference key="source" ref="1001"/>
<reference key="destination" ref="819368832"/>
</object>
<int key="connectionID">263</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">dial:</string>
<reference key="source" ref="1001"/>
<reference key="destination" ref="693176110"/>
</object>
<int key="connectionID">264</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">dial:</string>
<reference key="source" ref="1001"/>
<reference key="destination" ref="667173404"/>
</object>
<int key="connectionID">265</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">dial:</string>
<reference key="source" ref="1001"/>
<reference key="destination" ref="632346904"/>
</object>
<int key="connectionID">266</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">dial:</string>
<reference key="source" ref="1001"/>
<reference key="destination" ref="92905949"/>
</object>
<int key="connectionID">267</int>
</object>
</object>
<object class="IBMutableOrderedSet" key="objectRecords">
<object class="NSArray" key="orderedObjects">
@ -2214,7 +2214,7 @@
</object>
</object>
<nil key="sourceID"/>
<int key="maxID">255</int>
<int key="maxID">267</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
@ -2235,24 +2235,13 @@
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>answer:</string>
<string>dial:</string>
<string>hangUp:</string>
<string>hold:</string>
<string>ignore:</string>
<string>micVolume:</string>
<string>muteMicrophone:</string>
<string>muteSpeakers:</string>
<string>n0:</string>
<string>n1:</string>
<string>n2:</string>
<string>n3:</string>
<string>n4:</string>
<string>n5:</string>
<string>n6:</string>
<string>n7:</string>
<string>n8:</string>
<string>n9:</string>
<string>nPound:</string>
<string>nStar:</string>
<string>showPad:</string>
<string>sound:</string>
<string>startRecording:</string>
@ -2272,17 +2261,6 @@
<string>id</string>
<string>id</string>
<string>id</string>
<string>id</string>
<string>id</string>
<string>id</string>
<string>id</string>
<string>id</string>
<string>id</string>
<string>id</string>
<string>id</string>
<string>id</string>
<string>id</string>
<string>id</string>
</object>
</object>
<object class="NSMutableDictionary" key="actionInfosByName">
@ -2290,24 +2268,13 @@
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>answer:</string>
<string>dial:</string>
<string>hangUp:</string>
<string>hold:</string>
<string>ignore:</string>
<string>micVolume:</string>
<string>muteMicrophone:</string>
<string>muteSpeakers:</string>
<string>n0:</string>
<string>n1:</string>
<string>n2:</string>
<string>n3:</string>
<string>n4:</string>
<string>n5:</string>
<string>n6:</string>
<string>n7:</string>
<string>n8:</string>
<string>n9:</string>
<string>nPound:</string>
<string>nStar:</string>
<string>showPad:</string>
<string>sound:</string>
<string>startRecording:</string>
@ -2319,6 +2286,10 @@
<string key="name">answer:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo">
<string key="name">dial:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo">
<string key="name">hangUp:</string>
<string key="candidateClassName">id</string>
@ -2343,54 +2314,6 @@
<string key="name">muteSpeakers:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo">
<string key="name">n0:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo">
<string key="name">n1:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo">
<string key="name">n2:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo">
<string key="name">n3:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo">
<string key="name">n4:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo">
<string key="name">n5:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo">
<string key="name">n6:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo">
<string key="name">n7:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo">
<string key="name">n8:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo">
<string key="name">n9:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo">
<string key="name">nPound:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo">
<string key="name">nStar:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo">
<string key="name">showPad:</string>
<string key="candidateClassName">id</string>
@ -2795,13 +2718,6 @@
<string key="minorKey">AppKit.framework/Headers/NSMenu.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AddressBook.framework/Headers/ABActions.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
@ -3053,13 +2969,6 @@
<string key="minorKey">Growl.framework/Headers/GrowlApplicationBridge.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">QTKit.framework/Headers/QTCaptureDecompressedAudioOutput.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
@ -3357,7 +3266,7 @@
<integer value="3000" key="NS.object.0"/>
</object>
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
<string key="IBDocument.LastKnownRelativeProjectPath">../../VoiceMac.xcodeproj</string>
<string key="IBDocument.LastKnownRelativeProjectPath">../../../VoiceMac.xcodeproj</string>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
<object class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
<bool key="EncodedWithXMLCoder">YES</bool>

View File

@ -1,8 +1,7 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Google Maps JavaScript API Example: Map Markers</title>
<title>Google Maps</title>
<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=ABQIAAAAubo60fwtNR25whNAx41blxT0XDzIA5Vc9Z_UCGrLZkM79S76tBTQZxiyIVg3CqAdOrtqQ0YzplaEXQ" type="text/javascript"></script>
<script type="text/javascript">
var map = null;

View File

@ -3,7 +3,7 @@ To get the latest source to PJProject, run the command below.
svn checkout http://svn.pjsip.org/repos/pjproject/trunk pjproject
To get the revision that I am using in VoiceMac and VoiceMob, run the command below.
svn checkout -r 3315 http://svn.pjsip.org/repos/pjproject/trunk pjproject
svn checkout -r 3334 http://svn.pjsip.org/repos/pjproject/trunk pjproject
Building.
To build for VoiceMac, run the command below.

View File

@ -439,10 +439,10 @@
2A11735C12456E4300D119B5 /* SIP */ = {
isa = PBXGroup;
children = (
2A11735D12456E4300D119B5 /* MGMSIPCallWindow.h */,
2A11735E12456E4300D119B5 /* MGMSIPCallWindow.m */,
2A11735F12456E4300D119B5 /* MGMSIPUser.h */,
2A11736012456E4300D119B5 /* MGMSIPUser.m */,
2A11735D12456E4300D119B5 /* MGMSIPCallWindow.h */,
2A11735E12456E4300D119B5 /* MGMSIPCallWindow.m */,
2A11736112456E4300D119B5 /* MGMSIPWavConverter.h */,
2A11736212456E4300D119B5 /* MGMSIPWavConverter.m */,
);