Prepare for 64 bit
[MacVim.git] / src / MacVim / Miscellaneous.m
blob3271c0549bbc4b06e477f73ec712859258ff434b
1 /* vi:set ts=8 sts=4 sw=4 ft=objc:
2  *
3  * VIM - Vi IMproved            by Bram Moolenaar
4  *                              MacVim GUI port by Bjorn Winckler
5  *
6  * Do ":help uganda"  in Vim to read copying and usage conditions.
7  * Do ":help credits" in Vim to see a list of people who contributed.
8  * See README.txt for an overview of the Vim source code.
9  */
11 #import "MacVim.h"
12 #import "Miscellaneous.h"
16 // NSUserDefaults keys
17 NSString *MMTabMinWidthKey              = @"MMTabMinWidth";
18 NSString *MMTabMaxWidthKey              = @"MMTabMaxWidth";
19 NSString *MMTabOptimumWidthKey          = @"MMTabOptimumWidth";
20 NSString *MMShowAddTabButtonKey         = @"MMShowAddTabButton";
21 NSString *MMTextInsetLeftKey            = @"MMTextInsetLeft";
22 NSString *MMTextInsetRightKey           = @"MMTextInsetRight";
23 NSString *MMTextInsetTopKey             = @"MMTextInsetTop";
24 NSString *MMTextInsetBottomKey          = @"MMTextInsetBottom";
25 NSString *MMTypesetterKey               = @"MMTypesetter";
26 NSString *MMCellWidthMultiplierKey      = @"MMCellWidthMultiplier";
27 NSString *MMBaselineOffsetKey           = @"MMBaselineOffset";
28 NSString *MMTranslateCtrlClickKey       = @"MMTranslateCtrlClick";
29 NSString *MMTopLeftPointKey             = @"MMTopLeftPoint";
30 NSString *MMOpenInCurrentWindowKey      = @"MMOpenInCurrentWindow";
31 NSString *MMNoFontSubstitutionKey       = @"MMNoFontSubstitution";
32 NSString *MMLoginShellKey               = @"MMLoginShell";
33 NSString *MMAtsuiRendererKey            = @"MMAtsuiRenderer";
34 NSString *MMUntitledWindowKey           = @"MMUntitledWindow";
35 NSString *MMTexturedWindowKey           = @"MMTexturedWindow";
36 NSString *MMZoomBothKey                 = @"MMZoomBoth";
37 NSString *MMCurrentPreferencePaneKey    = @"MMCurrentPreferencePane";
38 NSString *MMLoginShellCommandKey        = @"MMLoginShellCommand";
39 NSString *MMLoginShellArgumentKey       = @"MMLoginShellArgument";
40 NSString *MMDialogsTrackPwdKey          = @"MMDialogsTrackPwd";
41 #ifdef MM_ENABLE_PLUGINS
42 NSString *MMShowLeftPlugInContainerKey  = @"MMShowLeftPlugInContainer";
43 #endif
44 NSString *MMOpenLayoutKey               = @"MMOpenLayout";
45 NSString *MMVerticalSplitKey            = @"MMVerticalSplit";
46 NSString *MMPreloadCacheSizeKey         = @"MMPreloadCacheSize";
47 NSString *MMLastWindowClosedBehaviorKey = @"MMLastWindowClosedBehavior";
48 NSString *MMLoadDefaultFontKey          = @"MMLoadDefaultFont";
49 #ifdef INCLUDE_OLD_IM_CODE
50 NSString *MMUseInlineImKey              = @"MMUseInlineIm";
51 #endif // INCLUDE_OLD_IM_CODE
55 @implementation NSIndexSet (MMExtras)
57 + (id)indexSetWithVimList:(NSString *)list
59     NSMutableIndexSet *idxSet = [NSMutableIndexSet indexSet];
60     NSArray *array = [list componentsSeparatedByString:@"\n"];
61     unsigned i, count = [array count];
63     for (i = 0; i < count; ++i) {
64         NSString *entry = [array objectAtIndex:i];
65         if ([entry intValue] > 0)
66             [idxSet addIndex:i];
67     }
69     return idxSet;
72 @end // NSIndexSet (MMExtras)
77 @implementation NSDocumentController (MMExtras)
79 - (void)noteNewRecentFilePath:(NSString *)path
81     NSURL *url = [NSURL fileURLWithPath:path];
82     if (url)
83         [self noteNewRecentDocumentURL:url];
86 - (void)noteNewRecentFilePaths:(NSArray *)paths
88     NSEnumerator *e = [paths objectEnumerator];
89     NSString *path;
90     while ((path = [e nextObject]))
91         [self noteNewRecentFilePath:path];
94 @end // NSDocumentController (MMExtras)
99 @implementation NSSavePanel (MMExtras)
101 - (void)hiddenFilesButtonToggled:(id)sender
103     [self setShowsHiddenFiles:[sender intValue]];
106 - (void)setShowsHiddenFiles:(BOOL)show
108     // This is undocumented stuff, so be careful. This does the same as
109     //     [[self _navView] setShowsHiddenFiles:show];
110     // but does not produce warnings.
112     if (![self respondsToSelector:@selector(_navView)])
113         return;
115     id navView = [self performSelector:@selector(_navView)];
116     if (![navView respondsToSelector:@selector(setShowsHiddenFiles:)])
117         return;
119     // performSelector:withObject: does not support a BOOL
120     NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:
121         [navView methodSignatureForSelector:@selector(setShowsHiddenFiles:)]];
122     [invocation setTarget:navView];
123     [invocation setSelector:@selector(setShowsHiddenFiles:)];
124     [invocation setArgument:&show atIndex:2];
125     [invocation invoke];
128 @end // NSSavePanel (MMExtras)
133 @implementation NSMenu (MMExtras)
135 - (int)indexOfItemWithAction:(SEL)action
137     int i, count = [self numberOfItems];
138     for (i = 0; i < count; ++i) {
139         NSMenuItem *item = [self itemAtIndex:i];
140         if ([item action] == action)
141             return i;
142     }
144     return -1;
147 - (NSMenuItem *)itemWithAction:(SEL)action
149     int idx = [self indexOfItemWithAction:action];
150     return idx >= 0 ? [self itemAtIndex:idx] : nil;
153 - (NSMenu *)findMenuContainingItemWithAction:(SEL)action
155     // NOTE: We only look for the action in the submenus of 'self'
156     int i, count = [self numberOfItems];
157     for (i = 0; i < count; ++i) {
158         NSMenu *menu = [[self itemAtIndex:i] submenu];
159         NSMenuItem *item = [menu itemWithAction:action];
160         if (item) return menu;
161     }
163     return nil;
166 - (NSMenu *)findWindowsMenu
168     return [self findMenuContainingItemWithAction:
169         @selector(performMiniaturize:)];
172 - (NSMenu *)findApplicationMenu
174     // TODO: Just return [self itemAtIndex:0]?
175     return [self findMenuContainingItemWithAction:@selector(terminate:)];
178 - (NSMenu *)findServicesMenu
180     // NOTE!  Our heuristic for finding the "Services" menu is to look for the
181     // second item before the "Hide MacVim" menu item on the "MacVim" menu.
182     // (The item before "Hide MacVim" should be a separator, but this is not
183     // important as long as the item before that is the "Services" menu.)
185     NSMenu *appMenu = [self findApplicationMenu];
186     if (!appMenu) return nil;
188     int idx = [appMenu indexOfItemWithAction: @selector(hide:)];
189     if (idx-2 < 0) return nil;  // idx == -1, if selector not found
191     return [[appMenu itemAtIndex:idx-2] submenu];
194 - (NSMenu *)findFileMenu
196     return [self findMenuContainingItemWithAction:@selector(performClose:)];
199 @end // NSMenu (MMExtras)
204 @implementation NSToolbar (MMExtras)
206 - (NSUInteger)indexOfItemWithItemIdentifier:(NSString *)identifier
208     NSArray *items = [self items];
209     NSUInteger i, count = [items count];
210     for (i = 0; i < count; ++i) {
211         id item = [items objectAtIndex:i];
212         if ([[item itemIdentifier] isEqual:identifier])
213             return i;
214     }
216     return NSNotFound;
219 - (NSToolbarItem *)itemAtIndex:(NSUInteger)idx
221     NSArray *items = [self items];
222     if (idx < 0 || idx >= [items count])
223         return nil;
225     return [items objectAtIndex:idx];
228 - (NSToolbarItem *)itemWithItemIdentifier:(NSString *)identifier
230     NSUInteger idx = [self indexOfItemWithItemIdentifier:identifier];
231     return idx != NSNotFound ? [self itemAtIndex:idx] : nil;
234 @end // NSToolbar (MMExtras)
239 @implementation NSTabView (MMExtras)
241 - (void)removeAllTabViewItems
243     NSArray *existingItems = [self tabViewItems];
244     NSEnumerator *e = [existingItems objectEnumerator];
245     NSTabViewItem *item;
246     while ((item = [e nextObject])) {
247         [self removeTabViewItem:item];
248     }
251 @end // NSTabView (MMExtras)
256 @implementation NSNumber (MMExtras)
258 // HACK to allow font size to be changed via menu (bound to Cmd+/Cmd-)
259 - (NSInteger)tag
261     return [self intValue];
264 @end // NSNumber (MMExtras)
269     NSView *
270 showHiddenFilesView()
272     // Return a new button object for each NSOpenPanel -- several of them
273     // could be displayed at once.
274     // If the accessory view should get more complex, it should probably be
275     // loaded from a nib file.
276     NSButton *button = [[[NSButton alloc]
277         initWithFrame:NSMakeRect(0, 0, 140, 18)] autorelease];
278     [button setTitle:
279         NSLocalizedString(@"Show Hidden Files", @"Show Hidden Files Checkbox")];
280     [button setButtonType:NSSwitchButton];
282     [button setTarget:nil];
283     [button setAction:@selector(hiddenFilesButtonToggled:)];
285     // Use the regular control size (checkbox is a bit smaller without this)
286     NSControlSize buttonSize = NSRegularControlSize;
287     float fontSize = [NSFont systemFontSizeForControlSize:buttonSize];
288     NSCell *theCell = [button cell];
289     NSFont *theFont = [NSFont fontWithName:[[theCell font] fontName]
290                                       size:fontSize];
291     [theCell setFont:theFont];
292     [theCell setControlSize:buttonSize];
293     [button sizeToFit];
295     return button;
301     NSString *
302 normalizeFilename(NSString *filename)
304     return [filename precomposedStringWithCanonicalMapping];
307     NSArray *
308 normalizeFilenames(NSArray *filenames)
310     NSMutableArray *outnames = [NSMutableArray array];
311     if (!filenames)
312         return outnames;
314     unsigned i, count = [filenames count];
315     for (i = 0; i < count; ++i) {
316         NSString *nfkc = normalizeFilename([filenames objectAtIndex:i]);
317         [outnames addObject:nfkc];
318     }
320     return outnames;