Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 270 lines (229 sloc) 8.522 kB
76d2a5b @mstroeck
mstroeck authored
1 //
2 // NewPreferencesController.m
3 // Vienna
4 //
5 // Created by Steve on 10/15/05.
6 // Copyright (c) 2004-2005 Steve Palmer. All rights reserved.
7 //
8 // Licensed under the Apache License, Version 2.0 (the "License");
9 // you may not use this file except in compliance with the License.
10 // You may obtain a copy of the License at
11 //
12 // http://www.apache.org/licenses/LICENSE-2.0
13 //
14 // Unless required by applicable law or agreed to in writing, software
15 // distributed under the License is distributed on an "AS IS" BASIS,
16 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 // See the License for the specific language governing permissions and
18 // limitations under the License.
19 //
20
21 #import "NewPreferencesController.h"
22 #include <objc/runtime.h>
23
24 @interface NewPreferencesController (Private)
25 -(void)selectPane:(NSString *)identifier;
26 @end
27
28 @interface NSToolbar (NSToolbarPrivate)
29 -(NSView *)_toolbarView;
30 @end
31
32 @implementation NewPreferencesController
33
34 /* init
35 * Initialises a new instance of the new PreferencesController object.
36 */
37 -(id)init
38 {
39 if ((self = [super initWithWindowNibName:@"NewPreferences"]) != nil)
40 {
41 prefsDict = nil;
42 prefPanes = nil;
43 prefsIdentifiers = nil;
44 selectedIdentifier = nil;
45 }
46 return self;
47 }
48
49 /* awakeFromNib
50 * Do the things that only make sense after the window file is loaded.
51 */
52 -(void)awakeFromNib
53 {
54 static BOOL isPrimaryNib = YES;
55
56 // We get called for all view NIBs, so don't handle those or we'll stack overflow.
57 if (!isPrimaryNib)
58 return;
59
60 NSNotificationCenter * nc = [NSNotificationCenter defaultCenter];
61 [nc addObserver:self selector:@selector(handleGoogleAuthFailed:) name:@"MA_Notify_GoogleAuthFailed" object:nil];
62
63 // Load the NIBs using the plist to locate them and build the prefIdentifiersArray
64 // array of identifiers.
65 NSBundle * thisBundle = [NSBundle bundleForClass:[self class]];
66 NSString * pathToPList = [thisBundle pathForResource:@"Preferences.plist" ofType:@""];
67 NSAssert(pathToPList != nil, @"Missing Preferences.plist in build");
68
69 // Load the dictionary and sort the keys by name to create the ordered
70 // identifiers for each pane.
71 prefsDict = [[NSDictionary dictionaryWithContentsOfFile:pathToPList] retain];
72 prefsIdentifiers = [[[prefsDict allKeys] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)] retain];
73 NSAssert([prefsIdentifiers count] > 0, @"Empty Preferences.plist file");
74
75 // Set the title
76 [prefWindow setTitle:NSLocalizedString(@"Preferences", nil)];
77
78 // Create the toolbar
79 NSToolbar * toolbar = [[NSToolbar alloc] initWithIdentifier:@"PrefsToolbar"];
80 [toolbar setAllowsUserCustomization:NO];
81 [toolbar setAutosavesConfiguration:NO];
82 [toolbar setDisplayMode:NSToolbarDisplayModeIconAndLabel];
83 [toolbar setDelegate:self];
84 [prefWindow setToolbar:toolbar];
85 [toolbar release];
86
87 // Hide the toolbar pill button
88 [[prefWindow standardWindowButton:NSWindowToolbarButton] setFrame:NSZeroRect];
89
90 // Create an empty view
91 blankView = [[NSView alloc] initWithFrame:[[prefWindow contentView] frame]];
92
93 // Array of pane objects
94 prefPanes = [[NSMutableDictionary alloc] init];
95
96 // Center the window
97 [prefWindow center];
98
99 // Primary NIB is done.
100 isPrimaryNib = NO;
101
102 // Select the first pane
103 [self selectPane:[prefsIdentifiers objectAtIndex:0]];
104 }
105
106 -(void)handleGoogleAuthFailed:(NSNotification *)nc
107 {
108 if ([[self window] isVisible])
109 {
110 NSAlert *alert = [[[NSAlert alloc] init] autorelease];
111 [alert addButtonWithTitle:@"OK"];
112 [alert setMessageText:@"Google Authentication Failed"];
113 [alert setInformativeText:@"Please check your Google username and password in Vienna's preferences."];
114 [alert setAlertStyle:NSWarningAlertStyle];
115 [alert beginSheetModalForWindow:[self window] modalDelegate:self didEndSelector:nil contextInfo:nil];
116 }
117 }
118
119 /* itemForItemIdentifier
120 * Creates and returns an NSToolbarItem for the specified identifier.
121 */
122 -(NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdentifier willBeInsertedIntoToolbar:(BOOL)flag
123 {
124 NSToolbarItem * newItem = [[[NSToolbarItem alloc] initWithItemIdentifier:itemIdentifier] autorelease];
125 NSDictionary * prefsItem = [prefsDict objectForKey:itemIdentifier];
126 [newItem setLabel:NSLocalizedString([prefsItem valueForKey:@"Title"], nil)];
127 [newItem setTarget:self];
128 [newItem setAction:@selector(prefsPaneSelection:)];
129
130 NSString * prefImage = [prefsItem valueForKey:@"Image"];
131 if (prefImage != nil)
132 [newItem setImage:[NSImage imageNamed:prefImage]];
133 return newItem;
134 }
135
136 /* prefsPaneSelection
137 * Change the preference pane.
138 */
139 -(IBAction)prefsPaneSelection:(id)sender
140 {
141 NSToolbar * toolbar = [prefWindow toolbar];
142 [self selectPane:[toolbar selectedItemIdentifier]];
143 }
144
145 /* selectPane
146 * Activate the preference pane with the given identifier. Resize the main
147 * window to accommodate the pane contents.
148 */
149 -(void)selectPane:(NSString *)identifier
150 {
151 NSDictionary * prefItem = [prefsDict objectForKey:identifier];
152 NSAssert(prefItem != nil, @"Not a valid preference identifier");
153
154 // Skip if we're already the selected pane
155 if ([identifier isEqualToString:selectedIdentifier])
156 return;
157
158 // Make sure the associated class has been instantiated
159 id prefPane = [prefPanes objectForKey:identifier];
160 if (prefPane == nil)
161 {
162 NSString * className = [prefItem objectForKey:@"ClassName"];
163 if (className == nil)
164 {
165 NSLog(@"Missing ClassName attribute from preference %@", identifier);
166 return;
167 }
168 Class classObject = objc_getClass([className cStringUsingEncoding:NSASCIIStringEncoding]);
169 if (classObject == nil)
170 {
171 NSLog(@"Cannot find class '%@' in preference %@", className, identifier);
172 return;
173 }
174 prefPane = [[classObject alloc] init];
175 if (prefPane == nil)
176 return;
177
178 // This is the only safe time to add the pane to the array
179 [prefPanes setObject:prefPane forKey:identifier];
180 [prefPane release];
181 }
182
183 // If we get this far, OK to select the new item. Otherwise we're staying
184 // on the old one.
185 NSToolbar * toolbar = [prefWindow toolbar];
186 [toolbar setSelectedItemIdentifier:identifier];
187
188 if (selectedIdentifier != nil)
189 {
190 // Restore the pref pane to its original window
191 id oldPrefPane = [prefPanes objectForKey:selectedIdentifier];
192 NSView * oldView = [[prefWindow contentView] retain];
193 [prefWindow setContentView:nil];
194 [[oldPrefPane window] setContentView:oldView];
195 [oldView release];
196 }
197
198 // Now pull the new pane into view.
199 [prefWindow setContentView:blankView];
200 [prefWindow display];
201
202 // retain here, release after setting contentView
203 NSWindow * prefPaneWindow = [prefPane window];
204 NSView * theView = [[prefPaneWindow contentView] retain];
205 [prefPaneWindow setContentView:nil];
206
207 // Compute the new frame window height and width
208 NSRect windowFrame = [NSWindow contentRectForFrameRect:[prefWindow frame] styleMask:[prefWindow styleMask]];
209
210 float newWindowHeight = NSHeight([theView frame]) + NSHeight([[toolbar _toolbarView] frame]);
211 float newWindowWidth = NSWidth([theView frame]);
212
213 NSRect newFrameRect = NSMakeRect(NSMinX(windowFrame), NSMaxY(windowFrame) - newWindowHeight, newWindowWidth, newWindowHeight);
214 NSRect newWindowFrame = [NSWindow frameRectForContentRect:newFrameRect styleMask:[prefWindow styleMask]];
215 [prefWindow setFrame:newWindowFrame display:YES animate:[prefWindow isVisible]];
216
217 [prefWindow setContentView:theView];
218 [theView release]; // balance the retain above
219
220 // Remember this pane identifier.
221 [selectedIdentifier release];
222 selectedIdentifier = [identifier retain];
223 }
224
225 /* validateToolbarItem
226 * Every single toolbar item should be enabled.
227 */
228 -(BOOL)validateToolbarItem:(NSToolbarItem*)toolbarItem
229 {
230 return YES;
231 }
232
233 /* toolbarAllowedItemIdentifiers
234 * The allowed toolbar items. These are all preference items.
235 */
236 -(NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar *)toolbar
237 {
238 return prefsIdentifiers;
239 }
240
241 /* toolbarSelectableItemIdentifiers
242 * All the selectable toolbar items. This is everything, as usual.
243 */
244 -(NSArray *)toolbarSelectableItemIdentifiers:(NSToolbar *)toolbar
245 {
246 return prefsIdentifiers;
247 }
248
249 /* toolbarDefaultItemIdentifiers
250 * The default toolbar items. These are all preference items.
251 */
252 -(NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar *)toolbar
253 {
254 return prefsIdentifiers;
255 }
256
257 /* dealloc
258 * Clean up behind ourselves.
259 */
260 -(void)dealloc
261 {
262 [selectedIdentifier release];
263 [blankView release];
264 [prefPanes release];
265 [prefsIdentifiers release];
266 [prefsDict release];
267 [super dealloc];
268 }
269 @end
Something went wrong with that request. Please try again.