From a644448ef962551b0e9c7927f4c2f3b2c5890f41 Mon Sep 17 00:00:00 2001 From: GRMrGecko Date: Tue, 12 Oct 2010 00:53:17 -0500 Subject: [PATCH] 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. --- Classes/VoiceBase/MGMAddons.h | 2 +- Classes/VoiceBase/MGMAddons.m | 2 +- Classes/VoiceBase/MGMSound.m | 2 +- Classes/VoiceBase/SIP/MGMSIP.h | 2 + Classes/VoiceBase/SIP/MGMSIP.m | 15 +- Classes/VoiceBase/SIP/MGMSIPCall.h | 5 + Classes/VoiceBase/SIP/MGMSIPCall.m | 63 +++- Classes/VoiceBase/XML/MGMXMLElement.m | 1 + Classes/VoiceMac/Inbox/MGMInboxPlayWindow.m | 4 +- Classes/VoiceMac/Inbox/MGMInboxWindow.m | 6 +- Classes/VoiceMac/MGMController.m | 22 +- Classes/VoiceMac/MGMVoiceUser.h | 1 + Classes/VoiceMac/MGMVoiceUser.m | 18 +- Classes/VoiceMac/SIP/MGMSIPCallWindow.h | 17 +- Classes/VoiceMac/SIP/MGMSIPCallWindow.m | 90 +++-- Classes/VoiceMac/SIP/MGMSIPUser.h | 2 +- Classes/VoiceMac/SIP/MGMSIPUser.m | 12 +- Classes/VoiceMac/SMS/MGMSMSMessageView.m | 2 +- Classes/VoiceMac/Views/MGMPhoneFeild.m | 3 +- .../VoiceMac/English.lproj/SIPCallWindow.xib | 307 ++++++------------ Resources/VoiceMac/map.html | 5 +- SIP/notes.txt | 2 +- VoiceMac.xcodeproj/project.pbxproj | 4 +- 23 files changed, 279 insertions(+), 308 deletions(-) diff --git a/Classes/VoiceBase/MGMAddons.h b/Classes/VoiceBase/MGMAddons.h index 8ea1067..740b086 100644 --- a/Classes/VoiceBase/MGMAddons.h +++ b/Classes/VoiceBase/MGMAddons.h @@ -22,7 +22,7 @@ - (NSString *)replace:(NSString *)targetString with:(NSString *)replaceString; - (BOOL)containsString:(NSString *)string; -- (NSString *)escapeSMS; +- (NSString *)javascriptEscape; - (NSString *)filePath; - (NSString *)littersToNumbers; diff --git a/Classes/VoiceBase/MGMAddons.m b/Classes/VoiceBase/MGMAddons.m index 5c4192d..70c68ff 100644 --- a/Classes/VoiceBase/MGMAddons.m +++ b/Classes/VoiceBase/MGMAddons.m @@ -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:@"
"]; diff --git a/Classes/VoiceBase/MGMSound.m b/Classes/VoiceBase/MGMSound.m index ff09f7e..9309064 100644 --- a/Classes/VoiceBase/MGMSound.m +++ b/Classes/VoiceBase/MGMSound.m @@ -85,7 +85,7 @@ } - (void)play { - [sound play]; + [sound performSelectorOnMainThread:@selector(play) withObject:nil waitUntilDone:NO]; } - (void)pause { [sound pause]; diff --git a/Classes/VoiceBase/SIP/MGMSIP.h b/Classes/VoiceBase/SIP/MGMSIP.h index f657bc8..91f04fb 100644 --- a/Classes/VoiceBase/SIP/MGMSIP.h +++ b/Classes/VoiceBase/SIP/MGMSIP.h @@ -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; diff --git a/Classes/VoiceBase/SIP/MGMSIP.m b/Classes/VoiceBase/SIP/MGMSIP.m index 02387c0..acc700c 100644 --- a/Classes/VoiceBase/SIP/MGMSIP.m +++ b/Classes/VoiceBase/SIP/MGMSIP.m @@ -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; diff --git a/Classes/VoiceBase/SIP/MGMSIPCall.h b/Classes/VoiceBase/SIP/MGMSIPCall.h index a6b20a1..9d4f873 100644 --- a/Classes/VoiceBase/SIP/MGMSIPCall.h +++ b/Classes/VoiceBase/SIP/MGMSIPCall.h @@ -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; diff --git a/Classes/VoiceBase/SIP/MGMSIPCall.m b/Classes/VoiceBase/SIP/MGMSIPCall.m index aafd632..32dfdfd 100644 --- a/Classes/VoiceBase/SIP/MGMSIPCall.m +++ b/Classes/VoiceBase/SIP/MGMSIPCall.m @@ -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)); } diff --git a/Classes/VoiceBase/XML/MGMXMLElement.m b/Classes/VoiceBase/XML/MGMXMLElement.m index 233a6e6..be2bd57 100644 --- a/Classes/VoiceBase/XML/MGMXMLElement.m +++ b/Classes/VoiceBase/XML/MGMXMLElement.m @@ -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) { diff --git a/Classes/VoiceMac/Inbox/MGMInboxPlayWindow.m b/Classes/VoiceMac/Inbox/MGMInboxPlayWindow.m index bd9421c..a0cb896 100644 --- a/Classes/VoiceMac/Inbox/MGMInboxPlayWindow.m +++ b/Classes/VoiceMac/Inbox/MGMInboxPlayWindow.m @@ -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]; } diff --git a/Classes/VoiceMac/Inbox/MGMInboxWindow.m b/Classes/VoiceMac/Inbox/MGMInboxWindow.m index 45c5b46..9ce63c6 100644 --- a/Classes/VoiceMac/Inbox/MGMInboxWindow.m +++ b/Classes/VoiceMac/Inbox/MGMInboxWindow.m @@ -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) { diff --git a/Classes/VoiceMac/MGMController.m b/Classes/VoiceMac/MGMController.m index 5aea5a4..d3bacf9 100644 --- a/Classes/VoiceMac/MGMController.m +++ b/Classes/VoiceMac/MGMController.m @@ -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 { diff --git a/Classes/VoiceMac/MGMVoiceUser.h b/Classes/VoiceMac/MGMVoiceUser.h index bed3d25..d247d57 100644 --- a/Classes/VoiceMac/MGMVoiceUser.h +++ b/Classes/VoiceMac/MGMVoiceUser.h @@ -43,6 +43,7 @@ extern NSString *MGMLastUserPhoneKey; - (void)setInstanceInfo; - (BOOL)isPlacingCall; +- (void)donePlacingCall; - (IBAction)sms:(id)sender; diff --git a/Classes/VoiceMac/MGMVoiceUser.m b/Classes/VoiceMac/MGMVoiceUser.m index 0b4003d..db77e9a 100644 --- a/Classes/VoiceMac/MGMVoiceUser.m +++ b/Classes/VoiceMac/MGMVoiceUser.m @@ -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; - NSBeep(); - } + 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]; } diff --git a/Classes/VoiceMac/SIP/MGMSIPCallWindow.h b/Classes/VoiceMac/SIP/MGMSIPCallWindow.h index 454970a..bd08932 100644 --- a/Classes/VoiceMac/SIP/MGMSIPCallWindow.h +++ b/Classes/VoiceMac/SIP/MGMSIPCallWindow.h @@ -9,7 +9,7 @@ #if MGMSIPENABLED #import -@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 \ No newline at end of file diff --git a/Classes/VoiceMac/SIP/MGMSIPCallWindow.m b/Classes/VoiceMac/SIP/MGMSIPCallWindow.m index cfc25d5..8f65576 100644 --- a/Classes/VoiceMac/SIP/MGMSIPCallWindow.m +++ b/Classes/VoiceMac/SIP/MGMSIPCallWindow.m @@ -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,41 +331,31 @@ 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 { - [call sendDTMFDigits:@"1"]; -} -- (IBAction)n2:(id)sender { - [call sendDTMFDigits:@"2"]; -} -- (IBAction)n3:(id)sender { - [call sendDTMFDigits:@"3"]; -} -- (IBAction)n4:(id)sender { - [call sendDTMFDigits:@"4"]; -} -- (IBAction)n5:(id)sender { - [call sendDTMFDigits:@"5"]; -} -- (IBAction)n6:(id)sender { - [call sendDTMFDigits:@"6"]; -} -- (IBAction)n7:(id)sender { - [call sendDTMFDigits:@"7"]; -} -- (IBAction)n8:(id)sender { - [call sendDTMFDigits:@"8"]; -} -- (IBAction)n9:(id)sender { - [call sendDTMFDigits:@"9"]; -} -- (IBAction)n0:(id)sender { - [call sendDTMFDigits:@"0"]; -} -- (IBAction)nStar:(id)sender { - [call sendDTMFDigits:@"*"]; -} -- (IBAction)nPound:(id)sender { - [call sendDTMFDigits:@"#"]; +- (IBAction)dial:(id)sender { + if (sender==n1Button) + [call sendDTMFDigits:@"1"]; + else if (sender==n2Button) + [call sendDTMFDigits:@"2"]; + else if (sender==n3Button) + [call sendDTMFDigits:@"3"]; + else if (sender==n4Button) + [call sendDTMFDigits:@"4"]; + else if (sender==n5Button) + [call sendDTMFDigits:@"5"]; + else if (sender==n6Button) + [call sendDTMFDigits:@"6"]; + else if (sender==n7Button) + [call sendDTMFDigits:@"7"]; + else if (sender==n8Button) + [call sendDTMFDigits:@"8"]; + else if (sender==n9Button) + [call sendDTMFDigits:@"9"]; + else if (sender==nStarButton) + [call sendDTMFDigits:@"*"]; + else if (sender==n0Button) + [call sendDTMFDigits:@"0"]; + else if (sender==nPoundButton) + [call sendDTMFDigits:@"#"]; } - (void)reverseLookupDidFindInfo:(NSDictionary *)theInfo forRequest:(NSDictionary *)theRequest { diff --git a/Classes/VoiceMac/SIP/MGMSIPUser.h b/Classes/VoiceMac/SIP/MGMSIPUser.h index 828ef0b..bf401f8 100644 --- a/Classes/VoiceMac/SIP/MGMSIPUser.h +++ b/Classes/VoiceMac/SIP/MGMSIPUser.h @@ -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 diff --git a/Classes/VoiceMac/SIP/MGMSIPUser.m b/Classes/VoiceMac/SIP/MGMSIPUser.m index ffc365b..b950d6f 100644 --- a/Classes/VoiceMac/SIP/MGMSIPUser.m +++ b/Classes/VoiceMac/SIP/MGMSIPUser.m @@ -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]]; diff --git a/Classes/VoiceMac/SMS/MGMSMSMessageView.m b/Classes/VoiceMac/SMS/MGMSMSMessageView.m index 3d641d2..2916a2a 100644 --- a/Classes/VoiceMac/SMS/MGMSMSMessageView.m +++ b/Classes/VoiceMac/SMS/MGMSMSMessageView.m @@ -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();"]; } diff --git a/Classes/VoiceMac/Views/MGMPhoneFeild.m b/Classes/VoiceMac/Views/MGMPhoneFeild.m index e1ca7e0..b701b36 100644 --- a/Classes/VoiceMac/Views/MGMPhoneFeild.m +++ b/Classes/VoiceMac/Views/MGMPhoneFeild.m @@ -159,7 +159,8 @@ - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView*)controlView { [super drawWithFrame:cellFrame inView:controlView]; - [clearButton drawWithFrame:[self clearButtonRectForBounds:cellFrame] inView:controlView]; + if ([[self stringValue] length]>0) + [clearButton drawWithFrame:[self clearButtonRectForBounds:cellFrame] inView:controlView]; } - (void)resetCursorRect:(NSRect)cellFrame inView:(NSView *)controlView { diff --git a/Resources/VoiceMac/English.lproj/SIPCallWindow.xib b/Resources/VoiceMac/English.lproj/SIPCallWindow.xib index bf24ff2..0a4892c 100644 --- a/Resources/VoiceMac/English.lproj/SIPCallWindow.xib +++ b/Resources/VoiceMac/English.lproj/SIPCallWindow.xib @@ -12,9 +12,9 @@ YES - - + + YES @@ -231,7 +231,7 @@ 68288064 4195328 - 00:00:00 + 0:00:00 LucidaGrande 13 @@ -397,7 +397,7 @@ 68288064 4195328 - Status Message + Disconnected @@ -1230,102 +1230,6 @@ 224 - - - n1: - - - - 230 - - - - n2: - - - - 231 - - - - n3: - - - - 232 - - - - n4: - - - - 233 - - - - n5: - - - - 234 - - - - n6: - - - - 235 - - - - n7: - - - - 236 - - - - n8: - - - - 237 - - - - n9: - - - - 238 - - - - nStar: - - - - 239 - - - - nPound: - - - - 240 - - - - n0: - - - - 241 - showPadButton @@ -1414,6 +1318,102 @@ 255 + + + dial: + + + + 256 + + + + dial: + + + + 257 + + + + dial: + + + + 258 + + + + dial: + + + + 259 + + + + dial: + + + + 260 + + + + dial: + + + + 261 + + + + dial: + + + + 262 + + + + dial: + + + + 263 + + + + dial: + + + + 264 + + + + dial: + + + + 265 + + + + dial: + + + + 266 + + + + dial: + + + + 267 + @@ -2214,7 +2214,7 @@ - 255 + 267 @@ -2235,24 +2235,13 @@ YES answer: + dial: hangUp: hold: ignore: micVolume: muteMicrophone: muteSpeakers: - n0: - n1: - n2: - n3: - n4: - n5: - n6: - n7: - n8: - n9: - nPound: - nStar: showPad: sound: startRecording: @@ -2272,17 +2261,6 @@ id id id - id - id - id - id - id - id - id - id - id - id - id @@ -2290,24 +2268,13 @@ YES answer: + dial: hangUp: hold: ignore: micVolume: muteMicrophone: muteSpeakers: - n0: - n1: - n2: - n3: - n4: - n5: - n6: - n7: - n8: - n9: - nPound: - nStar: showPad: sound: startRecording: @@ -2319,6 +2286,10 @@ answer: id + + dial: + id + hangUp: id @@ -2343,54 +2314,6 @@ muteSpeakers: id - - n0: - id - - - n1: - id - - - n2: - id - - - n3: - id - - - n4: - id - - - n5: - id - - - n6: - id - - - n7: - id - - - n8: - id - - - n9: - id - - - nPound: - id - - - nStar: - id - showPad: id @@ -2795,13 +2718,6 @@ AppKit.framework/Headers/NSMenu.h - - NSObject - - IBFrameworkSource - AddressBook.framework/Headers/ABActions.h - - NSObject @@ -3053,13 +2969,6 @@ Growl.framework/Headers/GrowlApplicationBridge.h - - NSObject - - IBFrameworkSource - QTKit.framework/Headers/QTCaptureDecompressedAudioOutput.h - - NSObject @@ -3357,7 +3266,7 @@ YES - ../../VoiceMac.xcodeproj + ../../../VoiceMac.xcodeproj 3 YES diff --git a/Resources/VoiceMac/map.html b/Resources/VoiceMac/map.html index 8b0df6c..9303d9a 100644 --- a/Resources/VoiceMac/map.html +++ b/Resources/VoiceMac/map.html @@ -1,8 +1,7 @@ - - + - Google Maps JavaScript API Example: Map Markers + Google Maps