diff --git a/src/MacVim/MMBackend.h b/src/MacVim/MMBackend.h index 96e7688029..ede19c43db 100644 --- a/src/MacVim/MMBackend.h +++ b/src/MacVim/MMBackend.h @@ -84,10 +84,8 @@ - (void)setRows:(int)rows columns:(int)cols; - (void)setWindowTitle:(char *)title; - (void)setDocumentFilename:(char *)filename; -- (char *)browseForFileInDirectory:(char *)dir title:(char *)title - saving:(int)saving; -- (int)presentDialogWithType:(int)type title:(char *)title message:(char *)msg - buttons:(char *)btns textField:(char *)txtfield; +- (char *)browseForFileWithAttributes:(NSDictionary *)attr; +- (int)showDialogWithAttributes:(NSDictionary *)attr textField:(char *)txtfield; - (void)showToolbar:(int)enable flags:(int)flags; - (void)createScrollbarWithIdentifier:(long)ident type:(int)type; - (void)destroyScrollbarWithIdentifier:(long)ident; diff --git a/src/MacVim/MMBackend.m b/src/MacVim/MMBackend.m index b385357dc9..251ae289eb 100644 --- a/src/MacVim/MMBackend.m +++ b/src/MacVim/MMBackend.m @@ -653,17 +653,12 @@ static NSString *MMSymlinkWarningString = [self queueMessage:SetDocumentFilenameMsgID data:data]; } -- (char *)browseForFileInDirectory:(char *)dir title:(char *)title - saving:(int)saving +- (char *)browseForFileWithAttributes:(NSDictionary *)attr { - //NSLog(@"browseForFileInDirectory:%s title:%s saving:%d", dir, title, - // saving); - char_u *s = NULL; - NSString *ds = dir ? [NSString stringWithUTF8String:dir] : nil; - NSString *ts = title ? [NSString stringWithUTF8String:title] : nil; + @try { - [frontendProxy showSavePanelForDirectory:ds title:ts saving:saving]; + [frontendProxy showSavePanelWithAttributes:attr]; [self waitForDialogReturn]; @@ -687,7 +682,7 @@ static NSString *MMSymlinkWarningString = return (char *)s; } -- (void)setDialogReturn:(in bycopy id)obj +- (oneway void)setDialogReturn:(in bycopy id)obj { // NOTE: This is called by // - [MMVimController panelDidEnd:::], and @@ -705,47 +700,12 @@ static NSString *MMSymlinkWarningString = } } -- (int)presentDialogWithType:(int)type title:(char *)title message:(char *)msg - buttons:(char *)btns textField:(char *)txtfield +- (int)showDialogWithAttributes:(NSDictionary *)attr textField:(char *)txtfield { int retval = 0; - NSString *message = nil, *text = nil, *textFieldString = nil; - NSArray *buttons = nil; - int style = NSInformationalAlertStyle; - - if (VIM_WARNING == type) style = NSWarningAlertStyle; - else if (VIM_ERROR == type) style = NSCriticalAlertStyle; - - if (btns) { - NSString *btnString = [NSString stringWithUTF8String:btns]; - buttons = [btnString componentsSeparatedByString:@"\n"]; - } - if (title) - message = [NSString stringWithUTF8String:title]; - if (msg) { - text = [NSString stringWithUTF8String:msg]; - if (!message) { - // HACK! If there is a '\n\n' or '\n' sequence in the message, then - // make the part up to there into the title. We only do this - // because Vim has lots of dialogs without a title and they look - // ugly that way. - // TODO: Fix the actual dialog texts. - NSRange eolRange = [text rangeOfString:@"\n\n"]; - if (NSNotFound == eolRange.location) - eolRange = [text rangeOfString:@"\n"]; - if (NSNotFound != eolRange.location) { - message = [text substringToIndex:eolRange.location]; - text = [text substringFromIndex:NSMaxRange(eolRange)]; - } - } - } - if (txtfield) - textFieldString = [NSString stringWithUTF8String:txtfield]; @try { - [frontendProxy presentDialogWithStyle:style message:message - informativeText:text buttonTitles:buttons - textFieldString:textFieldString]; + [frontendProxy presentDialogWithAttributes:attr]; [self waitForDialogReturn]; diff --git a/src/MacVim/MMVimController.m b/src/MacVim/MMVimController.m index b8e5662a7b..6689a9207c 100644 --- a/src/MacVim/MMVimController.m +++ b/src/MacVim/MMVimController.m @@ -383,13 +383,26 @@ static BOOL isUnsafeMessage(int msgid); [windowController cleanup]; } -- (oneway void)showSavePanelForDirectory:(in bycopy NSString *)dir - title:(in bycopy NSString *)title - saving:(int)saving +- (oneway void)showSavePanelWithAttributes:(in bycopy NSDictionary *)attr { - // TODO: Delay call until run loop is in default mode. if (!isInitialized) return; + BOOL inDefaultMode = [[[NSRunLoop currentRunLoop] currentMode] + isEqual:NSDefaultRunLoopMode]; + if (!inDefaultMode) { + // Delay call until run loop is in default mode. + [self performSelectorOnMainThread: + @selector(showSavePanelWithAttributes:) + withObject:attr + waitUntilDone:NO + modes:[NSArray arrayWithObject: + NSDefaultRunLoopMode]]; + return; + } + + NSString *dir = [attr objectForKey:@"dir"]; + BOOL saving = [[attr objectForKey:@"saving"] boolValue]; + if (!dir) { // 'dir == nil' means: set dir to the pwd of the Vim process, or let // open dialog decide (depending on the below user default). @@ -418,15 +431,29 @@ static BOOL isUnsafeMessage(int msgid); } } -- (oneway void)presentDialogWithStyle:(int)style - message:(in bycopy NSString *)message - informativeText:(in bycopy NSString *)text - buttonTitles:(in bycopy NSArray *)buttonTitles - textFieldString:(in bycopy NSString *)textFieldString +- (oneway void)presentDialogWithAttributes:(in bycopy NSDictionary *)attr { - // TODO: Delay call until run loop is in default mode. - if (!(windowController && buttonTitles && [buttonTitles count])) return; + if (!isInitialized) return; + BOOL inDefaultMode = [[[NSRunLoop currentRunLoop] currentMode] + isEqual:NSDefaultRunLoopMode]; + if (!inDefaultMode) { + // Delay call until run loop is in default mode. + [self performSelectorOnMainThread:@selector(presentDialogWithStyle:) + withObject:attr + waitUntilDone:NO + modes:[NSArray arrayWithObject: + NSDefaultRunLoopMode]]; + return; + } + + NSArray *buttonTitles = [attr objectForKey:@"buttonTitles"]; + if (!(buttonTitles && [buttonTitles count])) return; + + int style = [[attr objectForKey:@"alertStyle"] intValue]; + NSString *message = [attr objectForKey:@"messageText"]; + NSString *text = [attr objectForKey:@"informativeText"]; + NSString *textFieldString = [attr objectForKey:@"textFieldString"]; MMAlert *alert = [[MMAlert alloc] init]; // NOTE! This has to be done before setting the informative text. diff --git a/src/MacVim/MacVim.h b/src/MacVim/MacVim.h index 44486b032a..5e7bc8becc 100644 --- a/src/MacVim/MacVim.h +++ b/src/MacVim/MacVim.h @@ -29,7 +29,7 @@ @protocol MMBackendProtocol - (oneway void)processInput:(int)msgid data:(in bycopy NSData *)data; - (oneway void)processInputAndData:(in bycopy NSArray *)messages; -- (void)setDialogReturn:(in bycopy id)obj; +- (oneway void)setDialogReturn:(in bycopy id)obj; - (NSString *)evaluateExpression:(in bycopy NSString *)expr; - (BOOL)starRegisterToPasteboard:(byref NSPasteboard *)pboard; @end @@ -45,14 +45,8 @@ // @protocol MMFrontendProtocol - (oneway void)processCommandQueue:(in bycopy NSArray *)queue; -- (oneway void)showSavePanelForDirectory:(in bycopy NSString *)dir - title:(in bycopy NSString *)title - saving:(int)saving; -- (oneway void)presentDialogWithStyle:(int)style - message:(in bycopy NSString *)message - informativeText:(in bycopy NSString *)text - buttonTitles:(in bycopy NSArray *)buttonTitles - textFieldString:(in bycopy NSString *)textFieldString; +- (oneway void)showSavePanelWithAttributes:(in bycopy NSDictionary *)attr; +- (oneway void)presentDialogWithAttributes:(in bycopy NSDictionary *)attr; @end diff --git a/src/MacVim/gui_macvim.m b/src/MacVim/gui_macvim.m index e2320f43f9..4476d8b577 100644 --- a/src/MacVim/gui_macvim.m +++ b/src/MacVim/gui_macvim.m @@ -1307,19 +1307,14 @@ gui_mch_browse( // Ensure no data is on the output queue before presenting the dialog. gui_macvim_force_flush(); -#ifdef FEAT_MBYTE - title = CONVERT_TO_UTF8(title); - initdir = CONVERT_TO_UTF8(initdir); -#endif + NSMutableDictionary *attr = [NSMutableDictionary + dictionaryWithObject:[NSNumber numberWithBool:saving] + forKey:@"saving"]; + if (initdir) + [attr setObject:[NSString stringWithVimString:initdir] forKey:@"dir"]; char_u *s = (char_u*)[[MMBackend sharedInstance] - browseForFileInDirectory:(char*)initdir title:(char*)title - saving:saving]; - -#ifdef FEAT_MBYTE - CONVERT_TO_UTF8_FREE(title); - CONVERT_TO_UTF8_FREE(initdir); -#endif + browseForFileWithAttributes:attr]; return s; } @@ -1343,28 +1338,57 @@ gui_mch_dialog( // Ensure no data is on the output queue before presenting the dialog. gui_macvim_force_flush(); -#ifdef FEAT_MBYTE - title = CONVERT_TO_UTF8(title); - message = CONVERT_TO_UTF8(message); - buttons = CONVERT_TO_UTF8(buttons); - textfield = CONVERT_TO_UTF8(textfield); -#endif + int style = NSInformationalAlertStyle; + if (VIM_WARNING == type) style = NSWarningAlertStyle; + else if (VIM_ERROR == type) style = NSCriticalAlertStyle; - int ret = [[MMBackend sharedInstance] - presentDialogWithType:type - title:(char*)title - message:(char*)message - buttons:(char*)buttons - textField:(char*)textfield]; + NSMutableDictionary *attr = [NSMutableDictionary + dictionaryWithObject:[NSNumber numberWithInt:style] + forKey:@"alertStyle"]; -#ifdef FEAT_MBYTE - CONVERT_TO_UTF8_FREE(title); - CONVERT_TO_UTF8_FREE(message); - CONVERT_TO_UTF8_FREE(buttons); - CONVERT_TO_UTF8_FREE(textfield); -#endif + if (buttons) { + // 'buttons' is a string of '\n'-separated button titles + NSString *string = [NSString stringWithVimString:buttons]; + NSArray *array = [string componentsSeparatedByString:@"\n"]; + [attr setObject:array forKey:@"buttonTitles"]; + } - return ret; + NSString *messageText = nil; + if (title) + messageText = [NSString stringWithVimString:title]; + + if (message) { + NSString *informativeText = [NSString stringWithVimString:message]; + if (!messageText) { + // HACK! If there is a '\n\n' or '\n' sequence in the message, then + // make the part up to there into the title. We only do this + // because Vim has lots of dialogs without a title and they look + // ugly that way. + // TODO: Fix the actual dialog texts. + NSRange eolRange = [informativeText rangeOfString:@"\n\n"]; + if (NSNotFound == eolRange.location) + eolRange = [informativeText rangeOfString:@"\n"]; + if (NSNotFound != eolRange.location) { + messageText = [informativeText substringToIndex: + eolRange.location]; + informativeText = [informativeText substringFromIndex: + NSMaxRange(eolRange)]; + } + } + + [attr setObject:informativeText forKey:@"informativeText"]; + } + + if (messageText) + [attr setObject:messageText forKey:@"messageText"]; + + if (textfield) { + NSString *string = [NSString stringWithVimString:textfield]; + [attr setObject:string forKey:@"textFieldString"]; + } + + return [[MMBackend sharedInstance] showDialogWithAttributes:attr + textField:(char*)textfield]; }