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