Add support for dialogs

This commit is contained in:
Bjorn Winckler
2009-04-05 18:57:56 +02:00
parent 27d4ee55ae
commit cd5ca1918d
5 changed files with 166 additions and 147 deletions
+9
View File
@@ -1183,6 +1183,15 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
NSLog(@"[%s] Appending queue id=%d", _cmd, identifier);
q = [q arrayByAddingObjectsFromArray:queue];
[inputQueues setObject:q forKey:key];
#if 0 // More debug logging info
unsigned i, count = [q count];
for (i = 0; i < count; i += 2) {
NSData *value = [q objectAtIndex:i];
int msgid = *((int*)[value bytes]);
NSLog(@" %s", MessageStrings[msgid]);
}
#endif
} else {
[inputQueues setObject:queue forKey:key];
}
+9 -10
View File
@@ -691,10 +691,10 @@ extern GuiFont gui_mch_retain_font(GuiFont font);
{
char_u *s = NULL;
#if 0
@try {
[frontendProxy showSavePanelWithAttributes:attr];
[self queueMessage:BrowseForFileMsgID properties:attr];
[self flushQueue:YES];
@try {
[self waitForDialogReturn];
if (dialogReturn && [dialogReturn isKindOfClass:[NSString class]])
@@ -703,9 +703,9 @@ extern GuiFont gui_mch_retain_font(GuiFont font);
[dialogReturn release]; dialogReturn = nil;
}
@catch (NSException *e) {
NSLog(@"Exception caught when showing save panel: \"%@\"", e);
NSLog(@"[%s] Exception caught: \"%@\"", _cmd, e);
}
#endif
return (char *)s;
}
@@ -731,10 +731,10 @@ extern GuiFont gui_mch_retain_font(GuiFont font);
{
int retval = 0;
#if 0
@try {
[frontendProxy presentDialogWithAttributes:attr];
[self queueMessage:ShowDialogMsgID properties:attr];
[self flushQueue:YES];
@try {
[self waitForDialogReturn];
if (dialogReturn && [dialogReturn isKindOfClass:[NSArray class]]
@@ -756,9 +756,8 @@ extern GuiFont gui_mch_retain_font(GuiFont font);
[dialogReturn release]; dialogReturn = nil;
}
@catch (NSException *e) {
NSLog(@"Exception caught while showing alert dialog: \"%@\"", e);
NSLog(@"[%s] Exception caught: \"%@\"", _cmd, e);
}
#endif
return retval;
}
+144 -137
View File
@@ -97,6 +97,8 @@ static unsigned identifierCounter = 1;
- (void)popupMenuWithAttributes:(NSDictionary *)attrs;
- (void)connectionDidDie:(NSNotification *)notification;
- (void)scheduleClose;
- (void)handleBrowseForFile:(NSDictionary *)attr;
- (void)handleShowDialog:(NSDictionary *)attr;
@end
@@ -439,143 +441,6 @@ static unsigned identifierCounter = 1;
[windowController cleanup];
}
#if 0
- (oneway void)showSavePanelWithAttributes:(in bycopy NSDictionary *)attr
{
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).
BOOL trackPwd = [[NSUserDefaults standardUserDefaults]
boolForKey:MMDialogsTrackPwdKey];
if (trackPwd)
dir = [vimState objectForKey:@"pwd"];
}
if (saving) {
[[NSSavePanel savePanel] beginSheetForDirectory:dir file:nil
modalForWindow:[windowController window]
modalDelegate:self
didEndSelector:@selector(savePanelDidEnd:code:context:)
contextInfo:NULL];
} else {
NSOpenPanel *panel = [NSOpenPanel openPanel];
[panel setAllowsMultipleSelection:NO];
[panel setAccessoryView:openPanelAccessoryView()];
[panel beginSheetForDirectory:dir file:nil types:nil
modalForWindow:[windowController window]
modalDelegate:self
didEndSelector:@selector(savePanelDidEnd:code:context:)
contextInfo:NULL];
}
}
- (oneway void)presentDialogWithAttributes:(in bycopy NSDictionary *)attr
{
if (!isInitialized) return;
BOOL inDefaultMode = [[[NSRunLoop currentRunLoop] currentMode]
isEqual:NSDefaultRunLoopMode];
if (!inDefaultMode) {
// Delay call until run loop is in default mode.
[self performSelectorOnMainThread:
@selector(presentDialogWithAttributes:)
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.
if (textFieldString)
[alert setTextFieldString:textFieldString];
[alert setAlertStyle:style];
if (message) {
[alert setMessageText:message];
} else {
// If no message text is specified 'Alert' is used, which we don't
// want, so set an empty string as message text.
[alert setMessageText:@""];
}
if (text) {
[alert setInformativeText:text];
} else if (textFieldString) {
// Make sure there is always room for the input text field.
[alert setInformativeText:@""];
}
unsigned i, count = [buttonTitles count];
for (i = 0; i < count; ++i) {
NSString *title = [buttonTitles objectAtIndex:i];
// NOTE: The title of the button may contain the character '&' to
// indicate that the following letter should be the key equivalent
// associated with the button. Extract this letter and lowercase it.
NSString *keyEquivalent = nil;
NSRange hotkeyRange = [title rangeOfString:@"&"];
if (NSNotFound != hotkeyRange.location) {
if ([title length] > NSMaxRange(hotkeyRange)) {
NSRange keyEquivRange = NSMakeRange(hotkeyRange.location+1, 1);
keyEquivalent = [[title substringWithRange:keyEquivRange]
lowercaseString];
}
NSMutableString *string = [NSMutableString stringWithString:title];
[string deleteCharactersInRange:hotkeyRange];
title = string;
}
[alert addButtonWithTitle:title];
// Set key equivalent for the button, but only if NSAlert hasn't
// already done so. (Check the documentation for
// - [NSAlert addButtonWithTitle:] to see what key equivalents are
// automatically assigned.)
NSButton *btn = [[alert buttons] lastObject];
if ([[btn keyEquivalent] length] == 0 && keyEquivalent) {
[btn setKeyEquivalent:keyEquivalent];
}
}
[alert beginSheetModalForWindow:[windowController window]
modalDelegate:self
didEndSelector:@selector(alertDidEnd:code:context:)
contextInfo:NULL];
[alert release];
}
#endif
- (void)processInputQueue:(NSArray *)queue
{
if (!isInitialized) return;
@@ -995,6 +860,14 @@ static unsigned identifierCounter = 1;
KeyScript(smKeySysScript);
} else if (DeactivateKeyScriptID == msgid) {
KeyScript(smKeyRoman);
} else if (BrowseForFileMsgID == msgid) {
NSDictionary *dict = [NSDictionary dictionaryWithData:data];
if (dict)
[self handleBrowseForFile:dict];
} else if (ShowDialogMsgID == msgid) {
NSDictionary *dict = [NSDictionary dictionaryWithData:data];
if (dict)
[self handleShowDialog:dict];
// IMPORTANT: When adding a new message, make sure to update
// isUnsafeMessage() if necessary!
} else {
@@ -1449,6 +1322,140 @@ static unsigned identifierCounter = 1;
NSDefaultRunLoopMode]];
}
- (void)handleBrowseForFile:(NSDictionary *)attr
{
if (!isInitialized) return;
BOOL inDefaultMode = [[[NSRunLoop currentRunLoop] currentMode]
isEqual:NSDefaultRunLoopMode];
if (!inDefaultMode) {
// Delay call until run loop is in default mode.
[self performSelectorOnMainThread:@selector(handleBrowseForFile:)
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).
BOOL trackPwd = [[NSUserDefaults standardUserDefaults]
boolForKey:MMDialogsTrackPwdKey];
if (trackPwd)
dir = [vimState objectForKey:@"pwd"];
}
if (saving) {
[[NSSavePanel savePanel] beginSheetForDirectory:dir file:nil
modalForWindow:[windowController window]
modalDelegate:self
didEndSelector:@selector(savePanelDidEnd:code:context:)
contextInfo:NULL];
} else {
NSOpenPanel *panel = [NSOpenPanel openPanel];
[panel setAllowsMultipleSelection:NO];
[panel setAccessoryView:openPanelAccessoryView()];
[panel beginSheetForDirectory:dir file:nil types:nil
modalForWindow:[windowController window]
modalDelegate:self
didEndSelector:@selector(savePanelDidEnd:code:context:)
contextInfo:NULL];
}
}
- (void)handleShowDialog:(NSDictionary *)attr
{
if (!isInitialized) return;
BOOL inDefaultMode = [[[NSRunLoop currentRunLoop] currentMode]
isEqual:NSDefaultRunLoopMode];
if (!inDefaultMode) {
// Delay call until run loop is in default mode.
[self performSelectorOnMainThread:@selector(handleShowDialog:)
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.
if (textFieldString)
[alert setTextFieldString:textFieldString];
[alert setAlertStyle:style];
if (message) {
[alert setMessageText:message];
} else {
// If no message text is specified 'Alert' is used, which we don't
// want, so set an empty string as message text.
[alert setMessageText:@""];
}
if (text) {
[alert setInformativeText:text];
} else if (textFieldString) {
// Make sure there is always room for the input text field.
[alert setInformativeText:@""];
}
unsigned i, count = [buttonTitles count];
for (i = 0; i < count; ++i) {
NSString *title = [buttonTitles objectAtIndex:i];
// NOTE: The title of the button may contain the character '&' to
// indicate that the following letter should be the key equivalent
// associated with the button. Extract this letter and lowercase it.
NSString *keyEquivalent = nil;
NSRange hotkeyRange = [title rangeOfString:@"&"];
if (NSNotFound != hotkeyRange.location) {
if ([title length] > NSMaxRange(hotkeyRange)) {
NSRange keyEquivRange = NSMakeRange(hotkeyRange.location+1, 1);
keyEquivalent = [[title substringWithRange:keyEquivRange]
lowercaseString];
}
NSMutableString *string = [NSMutableString stringWithString:title];
[string deleteCharactersInRange:hotkeyRange];
title = string;
}
[alert addButtonWithTitle:title];
// Set key equivalent for the button, but only if NSAlert hasn't
// already done so. (Check the documentation for
// - [NSAlert addButtonWithTitle:] to see what key equivalents are
// automatically assigned.)
NSButton *btn = [[alert buttons] lastObject];
if ([[btn keyEquivalent] length] == 0 && keyEquivalent) {
[btn setKeyEquivalent:keyEquivalent];
}
}
[alert beginSheetModalForWindow:[windowController window]
modalDelegate:self
didEndSelector:@selector(alertDidEnd:code:context:)
contextInfo:NULL];
[alert release];
}
@end // MMVimController (Private)
+2
View File
@@ -182,6 +182,8 @@ enum {
FindReplaceMsgID,
ActivateKeyScriptID,
DeactivateKeyScriptID,
BrowseForFileMsgID,
ShowDialogMsgID,
};
+2
View File
@@ -86,6 +86,8 @@ char *MessageStrings[] =
"FindReplaceMsgID",
"ActivateKeyScriptID",
"DeactivateKeyScriptID",
"BrowseForFileMsgID",
"ShowDialogMsgID",
};