From 8ee6c93248bdab6f8bdd349bcc07d5cdd50df63a Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Sat, 1 Mar 2008 16:31:36 +0100 Subject: [PATCH] Integration prefs pane update - Make last prefs pane persistent - Order editor list alphabetically - Set editor on install if it is not set - Code cleanup --- src/MacVim/AuthorizedShellCommand.m | 5 +- src/MacVim/DBPrefsWindowController.m | 29 ++- src/MacVim/MMPreferenceController.m | 268 +++++++++++++++++---------- src/MacVim/MacVim.h | 1 + src/MacVim/MacVim.m | 1 + 5 files changed, 202 insertions(+), 102 deletions(-) diff --git a/src/MacVim/AuthorizedShellCommand.m b/src/MacVim/AuthorizedShellCommand.m index cca5b2bc0b..d3c8337a71 100644 --- a/src/MacVim/AuthorizedShellCommand.m +++ b/src/MacVim/AuthorizedShellCommand.m @@ -146,10 +146,7 @@ cleanup: free(authItems); - if (err != errAuthorizationSuccess) - return err; - - return noErr; + return err; } @end diff --git a/src/MacVim/DBPrefsWindowController.m b/src/MacVim/DBPrefsWindowController.m index d705e458fd..b58696fe1b 100644 --- a/src/MacVim/DBPrefsWindowController.m +++ b/src/MacVim/DBPrefsWindowController.m @@ -182,6 +182,24 @@ static DBPrefsWindowController *_sharedPrefsWindowController = nil; +- (NSString *)currentPaneIdentifier + // Subclasses can override this to persist the current preference pane. +{ + return currentPaneIdentifier; +} + + + + +- (void)setCurrentPaneIdentifier:(NSString *)identifier + // Subclasses can override this to persist the current preference pane. +{ + currentPaneIdentifier = identifier; +} + + + + #pragma mark - #pragma mark Overriding Methods @@ -211,11 +229,12 @@ static DBPrefsWindowController *_sharedPrefsWindowController = nil; [toolbar release]; } - if ([toolbarItems objectForKey:currentPaneIdentifier] == nil) { - currentPaneIdentifier = [toolbarIdentifiers objectAtIndex:0]; + if ([toolbarItems objectForKey:[self currentPaneIdentifier]] == nil) { + [self setCurrentPaneIdentifier:[toolbarIdentifiers objectAtIndex:0]]; } - [[[self window] toolbar] setSelectedItemIdentifier:currentPaneIdentifier]; - [self displayViewForIdentifier:currentPaneIdentifier animate:NO]; + [[[self window] toolbar] + setSelectedItemIdentifier:[self currentPaneIdentifier]]; + [self displayViewForIdentifier:[self currentPaneIdentifier] animate:NO]; [[self window] center]; @@ -271,7 +290,7 @@ static DBPrefsWindowController *_sharedPrefsWindowController = nil; - (void)toggleActivePreferenceView:(NSToolbarItem *)toolbarItem { [self displayViewForIdentifier:[toolbarItem itemIdentifier] animate:YES]; - currentPaneIdentifier = [toolbarItem itemIdentifier]; + [self setCurrentPaneIdentifier:[toolbarItem itemIdentifier]]; } diff --git a/src/MacVim/MMPreferenceController.m b/src/MacVim/MMPreferenceController.m index b3ee11a1f0..9e6f3f98b6 100644 --- a/src/MacVim/MMPreferenceController.m +++ b/src/MacVim/MMPreferenceController.m @@ -1,7 +1,7 @@ /* vi:set ts=8 sts=4 sw=4 ft=objc: * - * VIM - Vi IMproved by Bram Moolenaar - * MacVim GUI port by Bjorn Winckler + * VIM - Vi IMproved by Bram Moolenaar + * MacVim GUI port by Bjorn Winckler * * Do ":help uganda" in Vim to read copying and usage conditions. * Do ":help credits" in Vim to see a list of people who contributed. @@ -49,75 +49,86 @@ static NSString *ODBEDITOR_DIR = static NSString *ODBEDITOR_PATH = @"/Library/InputManagers/Edit in ODBEditor/Edit in ODBEditor.bundle"; + +NSString *kOdbEditorNameNone = @"(None)"; +NSString *kOdbEditorIdentifierNone = @""; + +NSString *kOdbEditorNameBBEdit = @"BBEdit"; +NSString *kOdbEditorIdentifierBBEdit = @"com.barebones.bbedit"; + +NSString *kOdbEditorNameCSSEdit = @"CSSEdit"; +NSString *kOdbEditorIdentifierCSSEdit = @"com.macrabbit.cssedit"; + +NSString *kOdbEditorNameMacVim = @"MacVim"; +NSString *kOdbEditorIdentifierMacVim = @"org.vim.MacVim"; + +NSString *kOdbEditorNameSmultron = @"Smultron"; +NSString *kOdbEditorIdentifierSmultron = @"org.smultron.Smultron"; + +NSString *kOdbEditorNameSubEthaEdit = @"SubEthaEdit"; +NSString *kOdbEditorIdentifierSubEthaEdit = @"de.codingmonkeys.SubEthaEdit"; + +NSString *kOdbEditorNameTextMate = @"TextMate"; +NSString *kOdbEditorIdentifierTextMate = @"com.macromates.textmate"; + +NSString *kOdbEditorNameTextWrangler = @"TextWrangler"; +NSString *kOdbEditorIdentifierTextWrangler = @"com.barebones.textwrangler"; + +NSString *kOdbEditorNameWriteRoom = @"WriteRoom"; +NSString *kOdbEditorIdentifierWriteRoom = @"com.hogbaysoftware.WriteRoom"; + + +@interface MMPreferenceController (Private) +// Integration pane +- (void)updateIntegrationPane; +- (void)setOdbEditorByName:(NSString *)name; +- (NSString *)odbEditorBundleIdentifier; +@end + @implementation MMPreferenceController -- (void)updateIntegrationPane +- (id)initWithWindow:(NSWindow *)window { - // XXX: check validation api. + self = [super initWithWindow:window]; + if (self == nil) + return nil; + // taken from Cyberduck. Thanks :-) + supportedOdbEditors = [[NSDictionary alloc] initWithObjectsAndKeys: + kOdbEditorIdentifierNone, kOdbEditorNameNone, + kOdbEditorIdentifierBBEdit, kOdbEditorNameBBEdit, + kOdbEditorIdentifierCSSEdit, kOdbEditorNameCSSEdit, + kOdbEditorIdentifierMacVim, kOdbEditorNameMacVim, + kOdbEditorIdentifierSmultron, kOdbEditorNameSmultron, + kOdbEditorIdentifierSubEthaEdit, kOdbEditorNameSubEthaEdit, + kOdbEditorIdentifierTextMate, kOdbEditorNameTextMate, + kOdbEditorIdentifierTextWrangler, kOdbEditorNameTextWrangler, + kOdbEditorIdentifierWriteRoom, kOdbEditorNameWriteRoom, + nil]; + return self; +} - // enable/disable buttons - - // can't use this, as it caches the bundle, so uninstallation is not - // detected - //NSBundle *inputManager = [NSBundle bundleWithPath:ODBEDITOR_PATH]; - //if (inputManager != nil) { - //NSString* v = - //[[inputManager infoDictionary] valueForKey:@"CFBundleVersion"]; - - // Check if ODB path exists before calling isFilePackageAtPath: otherwise - // an error is output to stderr on Tiger. - BOOL odbIsInstalled = - [[NSFileManager defaultManager] fileExistsAtPath:ODBEDITOR_PATH] - && [[NSWorkspace sharedWorkspace] isFilePackageAtPath:ODBEDITOR_PATH]; - - if (odbIsInstalled) { - [installOdbButton setTitle:@"Update"]; - [installOdbButton setEnabled:YES]; //XXX: only if there'a new version - [uninstallOdbButton setEnabled:YES]; - [editors setEnabled:YES]; - } else { - [installOdbButton setTitle:@"Install"]; - [installOdbButton setEnabled:YES]; - [uninstallOdbButton setEnabled:NO]; - [editors setEnabled:NO]; - } +- (void)dealloc +{ + [supportedOdbEditors release]; supportedOdbEditors = nil; + [super dealloc]; } - (void)awakeFromNib { - // reading the defaults of a different app is easier with carbon - NSString *bundleIdentifier = (NSString*)CFPreferencesCopyAppValue( - ODB_BUNDLE_IDENTIFIER, ODBEDITOR); - - // taken from Cyberduck. Thanks :-) - supportedOdbEditors = [[NSDictionary alloc] initWithObjectsAndKeys: - @"com.barebones.bbedit", @"BBEdit", - @"com.macrabbit.cssedit", @"CSSEdit", - @"org.vim.MacVim", @"MacVim", - @"org.smultron.Smultron", @"Smultron", - @"de.codingmonkeys.SubEthaEdit", @"SubEthaEdit", - @"com.macromates.textmate", @"TextMate", - @"com.barebones.textwrangler", @"TextWrangler", - @"com.hogbaysoftware.WriteRoom", @"WriteRoom", - @"", @"(None)", - nil]; - - NSString *selectedTitle = @"(None)"; - + // fill list of editors in integration pane + NSArray *keys = [[supportedOdbEditors allKeys] + sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)]; NSMenu *editorsMenu = [editors menu]; - NSEnumerator *enumerator = [supportedOdbEditors keyEnumerator]; + NSEnumerator *enumerator = [keys objectEnumerator]; NSString *key; while ((key = [enumerator nextObject]) != nil) { NSString *identifier = [supportedOdbEditors objectForKey:key]; - if (bundleIdentifier && [bundleIdentifier isEqualToString:identifier]) - selectedTitle = key; - NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:key action:@selector(odbEditorChanged:) keyEquivalent:@""]; [item setTarget:self]; - if (![identifier isEqualToString:@""]) { + if (![identifier isEqualToString:kOdbEditorIdentifierNone]) { NSString *appPath = [[NSWorkspace sharedWorkspace] absolutePathForAppBundleWithIdentifier:identifier]; [item setEnabled:appPath != nil]; @@ -132,39 +143,96 @@ static NSString *ODBEDITOR_PATH = [item release]; } - // XXX: if no pref is yet set, set it to MacVim (only if dropdown is - // active!) - [editors selectItemWithTitle:selectedTitle]; - [self updateIntegrationPane]; - - if (bundleIdentifier) - CFRelease(bundleIdentifier); } -- (void)dealloc +- (void)setupToolbar { - [supportedOdbEditors release]; supportedOdbEditors = nil; - [super dealloc]; + loadSymbols(); + + if (nsImageNamePreferencesGeneral != NULL) { + [self addView:generalPreferences + label:@"General" + image:[NSImage imageNamed:nsImageNamePreferencesGeneral]]; + } else { + [self addView:generalPreferences label:@"General"]; + } + + [self addView:integrationPreferences label:@"Integration"]; } + +- (NSString *)currentPaneIdentifier +{ + // We override this to persist the current pane. + return [[NSUserDefaults standardUserDefaults] + stringForKey:MMCurrentPreferencePaneKey]; +} + +- (void)setCurrentPaneIdentifier:(NSString *)identifier +{ + // We override this to persist the current pane. + [[NSUserDefaults standardUserDefaults] + setObject:identifier forKey:MMCurrentPreferencePaneKey]; +} + + - (BOOL)validateMenuItem:(NSMenuItem *)item { - NSString *identifier = [supportedOdbEditors objectForKey:[item title]]; - if (identifier == nil) - return NO; - if ([identifier isEqualToString:@""]) - return YES; - return [[NSWorkspace sharedWorkspace] - absolutePathForAppBundleWithIdentifier:identifier] != nil; + if ([item action] == @selector(odbEditorChanged:)) { + NSString *identifier = [supportedOdbEditors objectForKey:[item title]]; + if (identifier == nil) + return NO; + if ([identifier isEqualToString:kOdbEditorIdentifierNone]) + return YES; + return [[NSWorkspace sharedWorkspace] + absolutePathForAppBundleWithIdentifier:identifier] != nil; + } + return YES; } -- (void)odbEditorChanged:(id)sender -{ - NSString *name = [sender title]; - NSString *identifier = [supportedOdbEditors objectForKey:name]; +#pragma mark - +#pragma mark Integration pane - if (![identifier isEqualToString:@""]) { +- (void)updateIntegrationPane +{ + // XXX: check validation api. + // XXX: call this each time the dialog becomes active (so that if the + // user changes settings in terminal, the changes are reflected in the + // dialog) + + // Check if ODB path exists before calling isFilePackageAtPath: otherwise + // an error is output to stderr on Tiger. + BOOL odbIsInstalled = + [[NSFileManager defaultManager] fileExistsAtPath:ODBEDITOR_PATH] + && [[NSWorkspace sharedWorkspace] isFilePackageAtPath:ODBEDITOR_PATH]; + + // enable/disable buttons + if (odbIsInstalled) { + [installOdbButton setTitle:@"Update"]; + [installOdbButton setEnabled:YES]; //XXX: only if there'a new version + [uninstallOdbButton setEnabled:YES]; + [editors setEnabled:YES]; + } else { + [installOdbButton setTitle:@"Install"]; + [installOdbButton setEnabled:YES]; + [uninstallOdbButton setEnabled:NO]; + [editors setEnabled:NO]; + } + + // make sure the right editor is selected on the popup button + NSString *selectedTitle = kOdbEditorNameNone; + NSArray* keys = [supportedOdbEditors + allKeysForObject:[self odbEditorBundleIdentifier]]; + if ([keys count] > 0) + selectedTitle = [keys objectAtIndex:0]; + [editors selectItemWithTitle:selectedTitle]; +} + +- (void)setOdbEditorByName:(NSString *)name +{ + NSString *identifier = [supportedOdbEditors objectForKey:name]; + if (identifier != kOdbEditorIdentifierNone) { CFPreferencesSetAppValue(ODB_BUNDLE_IDENTIFIER, identifier, ODBEDITOR); CFPreferencesSetAppValue(ODB_EDITOR_NAME, name, ODBEDITOR); } else { @@ -174,6 +242,23 @@ static NSString *ODBEDITOR_PATH = CFPreferencesAppSynchronize(ODBEDITOR); } +// Note that you can't compare the result of this function with ==, you have +// to use isStringEqual: (since this returns a new copy of the string). +- (NSString *)odbEditorBundleIdentifier +{ + // reading the defaults of a different app is easier with carbon + NSString *bundleIdentifier = (NSString*)CFPreferencesCopyAppValue( + ODB_BUNDLE_IDENTIFIER, ODBEDITOR); + if (bundleIdentifier == nil) + return kOdbEditorIdentifierNone; + return [bundleIdentifier autorelease]; +} + +- (void)odbEditorChanged:(id)sender +{ + [self setOdbEditorByName:[sender title]]; +} + - (IBAction)installOdb:(id)sender { NSString *source = [[[NSBundle mainBundle] resourcePath] @@ -205,7 +290,17 @@ static NSString *ODBEDITOR_PATH = AuthorizedShellCommand *au = [[AuthorizedShellCommand alloc] initWithCommands:cmd]; - [au run]; + OSStatus err = [au run]; + if (err == errAuthorizationSuccess) { + // If the user just installed the input manager and no editor was + // selected before, chances are he wants to use MacVim as editor + if ([[self odbEditorBundleIdentifier] + isEqualToString:kOdbEditorIdentifierNone]) { + [self setOdbEditorByName:kOdbEditorNameMacVim]; + } + } else { + NSLog(@"Failed to install input manager, error is %d", err); + } [au release]; [self updateIntegrationPane]; @@ -221,25 +316,12 @@ static NSString *ODBEDITOR_PATH = AuthorizedShellCommand *au = [[AuthorizedShellCommand alloc] initWithCommands:cmd]; - [au run]; + OSStatus err = [au run]; + if (err != errAuthorizationSuccess) + NSLog(@"Failed to uninstall input manager, error is %d", err); [au release]; [self updateIntegrationPane]; } -- (void)setupToolbar -{ - loadSymbols(); - - if (nsImageNamePreferencesGeneral != NULL) { - [self addView:generalPreferences - label:@"General" - image:[NSImage imageNamed:nsImageNamePreferencesGeneral]]; - } else { - [self addView:generalPreferences label:@"General"]; - } - - [self addView:integrationPreferences label:@"Integration"]; -} - @end diff --git a/src/MacVim/MacVim.h b/src/MacVim/MacVim.h index ebfcf85490..dee990bd37 100644 --- a/src/MacVim/MacVim.h +++ b/src/MacVim/MacVim.h @@ -221,6 +221,7 @@ extern NSString *MMAtsuiRendererKey; extern NSString *MMUntitledWindowKey; extern NSString *MMTexturedWindowKey; extern NSString *MMZoomBothKey; +extern NSString *MMCurrentPreferencePaneKey; // Enum for MMUntitledWindowKey enum { diff --git a/src/MacVim/MacVim.m b/src/MacVim/MacVim.m index 8ec6aa5a1e..10e9c47ccb 100644 --- a/src/MacVim/MacVim.m +++ b/src/MacVim/MacVim.m @@ -101,6 +101,7 @@ NSString *MMAtsuiRendererKey = @"MMAtsuiRenderer"; NSString *MMUntitledWindowKey = @"MMUntitledWindow"; NSString *MMTexturedWindowKey = @"MMTexturedWindow"; NSString *MMZoomBothKey = @"MMZoomBoth"; +NSString *MMCurrentPreferencePaneKey = @"MMCurrentPreferencePane";