root / pithos-macos / PithosPreferencesController.m @ 3916144e
History | View | Annotate | Download (22.9 kB)
1 |
// |
---|---|
2 |
// PithosPreferencesController.m |
3 |
// pithos-macos |
4 |
// |
5 |
// Copyright 2011-2012 GRNET S.A. All rights reserved. |
6 |
// |
7 |
// Redistribution and use in source and binary forms, with or |
8 |
// without modification, are permitted provided that the following |
9 |
// conditions are met: |
10 |
// |
11 |
// 1. Redistributions of source code must retain the above |
12 |
// copyright notice, this list of conditions and the following |
13 |
// disclaimer. |
14 |
// |
15 |
// 2. Redistributions in binary form must reproduce the above |
16 |
// copyright notice, this list of conditions and the following |
17 |
// disclaimer in the documentation and/or other materials |
18 |
// provided with the distribution. |
19 |
// |
20 |
// THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS |
21 |
// OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
22 |
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
23 |
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR |
24 |
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
25 |
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
26 |
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
27 |
// USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
28 |
// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
29 |
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
30 |
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
31 |
// POSSIBILITY OF SUCH DAMAGE. |
32 |
// |
33 |
// The views and conclusions contained in the software and |
34 |
// documentation are those of the authors and should not be |
35 |
// interpreted as representing official policies, either expressed |
36 |
// or implied, of GRNET S.A. |
37 |
|
38 |
#import "PithosPreferencesController.h" |
39 |
#import "PithosBrowserController.h" |
40 |
#import "PithosAccountNode.h" |
41 |
#import "PithosContainerNode.h" |
42 |
#import "PithosSubdirNode.h" |
43 |
#import "PithosObjectNode.h" |
44 |
#import "PithosEmptyNode.h" |
45 |
#import "PithosAccount.h" |
46 |
#import "pithos_macosAppDelegate.h" |
47 |
|
48 |
#import "ImageAndTextCell.h" |
49 |
@interface PithosPreferencesSyncOutlineViewCell : ImageAndTextCell {} |
50 |
@end |
51 |
|
52 |
@implementation PithosPreferencesSyncOutlineViewCell |
53 |
|
54 |
- (void)setObjectValue:(id)object { |
55 |
if ([object isKindOfClass:[PithosNode class]]) { |
56 |
PithosNode *node = (PithosNode *)object; |
57 |
[self setStringValue:node.displayName]; |
58 |
[self setImage:node.icon]; |
59 |
[self setEditable:NO]; |
60 |
} else { |
61 |
[super setObjectValue:object]; |
62 |
} |
63 |
} |
64 |
|
65 |
@end |
66 |
|
67 |
@implementation PithosPreferencesController |
68 |
@synthesize selectedPithosAccount; |
69 |
@synthesize accountsArrayController; |
70 |
@synthesize accountRemoveEnable; |
71 |
@synthesize serverURL, authUser, authToken, manual, loginEnable, loginCancelEnable; |
72 |
@synthesize syncActive, syncDirectoryPath, syncContainersDictionary, syncApplyEnable, syncCancelEnable, |
73 |
syncContainersOutlineView, syncContainersRootFilesNodes; |
74 |
@synthesize groupsDictionaryController, selectedGroupMembersDictionaryController; |
75 |
|
76 |
#pragma mark - |
77 |
#pragma mark Object Lifecycle |
78 |
|
79 |
- (id)init { |
80 |
return [super initWithWindowNibName:@"PithosPreferencesController"]; |
81 |
} |
82 |
|
83 |
- (void)windowDidLoad { |
84 |
[super windowDidLoad]; |
85 |
|
86 |
NSWindow *window = [self window]; |
87 |
[window setHidesOnDeactivate:NO]; |
88 |
[window setExcludedFromWindowsMenu:YES]; |
89 |
|
90 |
// // Select the first tab when the window is loaded for the first time. |
91 |
// [[window valueForKeyPath:@"toolbar"] setSelectedItemIdentifier:@"0"]; |
92 |
|
93 |
[[[syncContainersOutlineView tableColumns] objectAtIndex:1] setDataCell:[[[PithosPreferencesSyncOutlineViewCell alloc] init] autorelease]]; |
94 |
|
95 |
[groupsDictionaryController setInitialKey:@"group"]; |
96 |
[groupsDictionaryController setInitialValue:@"user"]; |
97 |
[selectedGroupMembersDictionaryController setInitialKey:@"user"]; |
98 |
[selectedGroupMembersDictionaryController setInitialValue:@""]; |
99 |
|
100 |
[window setDelegate:self]; |
101 |
|
102 |
self.selectedPithosAccount = [[accountsArrayController selectedObjects] objectAtIndex:0]; |
103 |
[accountsArrayController addObserver:self forKeyPath:@"selection" options:NSKeyValueObservingOptionNew context:NULL]; |
104 |
[[NSNotificationCenter defaultCenter] addObserver:self |
105 |
selector:@selector(selectedPithosAccountNodeChildrenUpdated:) |
106 |
name:@"SelectedPithosAccountNodeChildrenUpdated" |
107 |
object:nil]; |
108 |
} |
109 |
|
110 |
- (BOOL)windowShouldClose:(id)sender { |
111 |
return [(pithos_macosAppDelegate *)[[NSApplication sharedApplication] delegate] activated]; |
112 |
} |
113 |
|
114 |
//- (void)windowWillClose:(NSNotification *)notification { |
115 |
//} |
116 |
|
117 |
//- (IBAction)toolbarItemSelected:(id)sender { |
118 |
//} |
119 |
|
120 |
#pragma mark - |
121 |
#pragma Observers |
122 |
|
123 |
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { |
124 |
if ([object isEqualTo:accountsArrayController] && |
125 |
[keyPath isEqualToString:@"selection"] && |
126 |
[[accountsArrayController selectedObjects] count]) { |
127 |
self.selectedPithosAccount = [[accountsArrayController selectedObjects] objectAtIndex:0]; |
128 |
} |
129 |
} |
130 |
|
131 |
- (void)selectedPithosAccountNodeChildrenUpdated:(NSNotification *)notification { |
132 |
[syncContainersOutlineView reloadData]; |
133 |
[syncContainersOutlineView expandItem:nil expandChildren:YES]; |
134 |
} |
135 |
|
136 |
#pragma mark - |
137 |
#pragma Update |
138 |
|
139 |
- (void)updateAccounts { |
140 |
pithos_macosAppDelegate *delegate = (pithos_macosAppDelegate *)[[NSApplication sharedApplication] delegate]; |
141 |
self.accountRemoveEnable = (delegate.activated && ([delegate.pithosAccounts count] > 1)); |
142 |
} |
143 |
|
144 |
- (void)updateLogin { |
145 |
self.loginEnable = ([selectedPithosAccount urlIsValid:serverURL] && (!manual || ([authUser length] && [authToken length]))); |
146 |
self.loginCancelEnable = (![selectedPithosAccount.serverURL isEqualToString:serverURL] || |
147 |
(selectedPithosAccount.authUser && ![selectedPithosAccount.authUser isEqualToString:authUser]) || |
148 |
(selectedPithosAccount.authToken && ![selectedPithosAccount.authToken isEqualToString:authToken])); |
149 |
} |
150 |
|
151 |
- (void)updateSync { |
152 |
BOOL isDirectory; |
153 |
self.syncApplyEnable = (selectedPithosAccount.active && |
154 |
((selectedPithosAccount.syncActive != syncActive) || |
155 |
(![selectedPithosAccount.syncDirectoryPath isEqualToString:syncDirectoryPath] && |
156 |
(![[NSFileManager defaultManager] fileExistsAtPath:syncDirectoryPath isDirectory:&isDirectory] || |
157 |
isDirectory)) || |
158 |
![selectedPithosAccount.syncContainersDictionary isEqualToDictionary:syncContainersDictionary])); |
159 |
self.syncCancelEnable = (selectedPithosAccount.active && |
160 |
((selectedPithosAccount.syncActive != syncActive) || |
161 |
![selectedPithosAccount.syncDirectoryPath isEqualToString:syncDirectoryPath] || |
162 |
![selectedPithosAccount.syncContainersDictionary isEqualToDictionary:syncContainersDictionary])); |
163 |
} |
164 |
|
165 |
#pragma mark - |
166 |
#pragma Properties |
167 |
|
168 |
- (void)setSelectedPithosAccount:(PithosAccount *)aSelectedPithosAccount { |
169 |
if (aSelectedPithosAccount && ![aSelectedPithosAccount isEqualTo:selectedPithosAccount]) { |
170 |
selectedPithosAccount.accountNode.childrenUpdatedNotificationName = nil; |
171 |
[selectedPithosAccount release]; |
172 |
selectedPithosAccount = [aSelectedPithosAccount retain]; |
173 |
selectedPithosAccount.accountNode.childrenUpdatedNotificationName = [NSString stringWithString:@"SelectedPithosAccountNodeChildrenUpdated"]; |
174 |
|
175 |
[self updateAccounts]; |
176 |
[self loginCancel:self]; |
177 |
[self syncCancel:self]; |
178 |
[self groupsRevert:self]; |
179 |
} |
180 |
} |
181 |
|
182 |
#pragma Login Properties |
183 |
|
184 |
- (void)setServerURL:(NSString *)aServerURL { |
185 |
[serverURL release]; |
186 |
serverURL = [aServerURL copy]; |
187 |
[self updateLogin]; |
188 |
} |
189 |
|
190 |
- (void)setAuthUser:(NSString *)anAuthUser { |
191 |
[authUser release]; |
192 |
authUser = [anAuthUser copy]; |
193 |
[self updateLogin]; |
194 |
} |
195 |
|
196 |
- (void)setAuthToken:(NSString *)anAuthToken { |
197 |
[authToken release]; |
198 |
authToken = [anAuthToken copy]; |
199 |
[self updateLogin]; |
200 |
} |
201 |
|
202 |
- (void)setManual:(BOOL)aManual { |
203 |
manual = aManual; |
204 |
[self updateLogin]; |
205 |
if (!manual) { |
206 |
self.authUser = selectedPithosAccount.authUser; |
207 |
self.authToken = selectedPithosAccount.authToken; |
208 |
} |
209 |
} |
210 |
|
211 |
#pragma Sync Properties |
212 |
|
213 |
- (void)setSyncActive:(BOOL)aSyncActive { |
214 |
syncActive = aSyncActive; |
215 |
[self updateSync]; |
216 |
} |
217 |
|
218 |
- (void)setSyncDirectoryPath:(NSString *)aSyncDirectoryPath { |
219 |
[syncDirectoryPath release]; |
220 |
syncDirectoryPath = [aSyncDirectoryPath copy]; |
221 |
[self updateSync]; |
222 |
} |
223 |
|
224 |
- (void)setSyncContainersDictionary:(NSMutableDictionary *)aSyncContainersDictionary { |
225 |
[syncContainersDictionary release]; |
226 |
syncContainersDictionary = [[NSMutableDictionary alloc] initWithCapacity:[aSyncContainersDictionary count]]; |
227 |
for (NSString *containerName in aSyncContainersDictionary) { |
228 |
[syncContainersDictionary setObject:[NSMutableArray arrayWithArray:[aSyncContainersDictionary objectForKey:containerName]] |
229 |
forKey:containerName]; |
230 |
} |
231 |
[self updateSync]; |
232 |
} |
233 |
|
234 |
#pragma mark - |
235 |
#pragma Actions |
236 |
|
237 |
- (IBAction)addAccount:(id)sender { |
238 |
[accountsArrayController addObject:[PithosAccount pithosAccount]]; |
239 |
[self updateAccounts]; |
240 |
pithos_macosAppDelegate *delegate = (pithos_macosAppDelegate *)[[NSApplication sharedApplication] delegate]; |
241 |
[delegate.pithosAccountsDictionary setObject:selectedPithosAccount forKey:selectedPithosAccount.name]; |
242 |
[delegate savePithosAccounts:self]; |
243 |
} |
244 |
|
245 |
- (IBAction)removeAccount:(id)sender { |
246 |
[self updateAccounts]; |
247 |
if (!accountRemoveEnable) |
248 |
return; |
249 |
PithosAccount *removedPithosAccount = [selectedPithosAccount retain]; |
250 |
pithos_macosAppDelegate *delegate = (pithos_macosAppDelegate *)[[NSApplication sharedApplication] delegate]; |
251 |
if ([delegate.currentPithosAccount isEqualTo:removedPithosAccount] && [delegate.pithosBrowserController operationsPending]) { |
252 |
NSAlert *alert = [[[NSAlert alloc] init] autorelease]; |
253 |
[alert setMessageText:@"Operations Pending"]; |
254 |
[alert setInformativeText:@"There are pending operations in the browser, do you want to remove the account and cancel them?"]; |
255 |
[alert addButtonWithTitle:@"OK"]; |
256 |
[alert addButtonWithTitle:@"Cancel"]; |
257 |
NSInteger choice = [alert runModal]; |
258 |
if (choice == NSAlertSecondButtonReturn) { |
259 |
[removedPithosAccount release]; |
260 |
return; |
261 |
} |
262 |
} |
263 |
[accountsArrayController removeObject:selectedPithosAccount]; |
264 |
[delegate.pithosAccountsDictionary removeObjectForKey:removedPithosAccount.name]; |
265 |
[delegate removedPithosAccount:removedPithosAccount]; |
266 |
[delegate savePithosAccounts:self]; |
267 |
[removedPithosAccount release]; |
268 |
[self updateAccounts]; |
269 |
} |
270 |
|
271 |
#pragma Login Actions |
272 |
|
273 |
- (IBAction)login:(id)sender { |
274 |
if (!manual) { |
275 |
[selectedPithosAccount loginWithServerURL:serverURL]; |
276 |
} else { |
277 |
[selectedPithosAccount authenticateWithServerURL:serverURL authUser:authUser authToken:authToken]; |
278 |
self.manual = NO; |
279 |
pithos_macosAppDelegate *delegate = (pithos_macosAppDelegate *)[[NSApplication sharedApplication] delegate]; |
280 |
[delegate savePithosAccounts:self]; |
281 |
if (!delegate.activated) { |
282 |
delegate.activated = YES; |
283 |
[delegate showPithosBrowser:self]; |
284 |
} |
285 |
if ([selectedPithosAccount isEqualTo:delegate.currentPithosAccount]) |
286 |
delegate.pithosBrowserController.pithos = selectedPithosAccount.pithos; |
287 |
} |
288 |
} |
289 |
|
290 |
- (IBAction)loginCancel:(id)server { |
291 |
self.serverURL = selectedPithosAccount.serverURL; |
292 |
self.authUser = selectedPithosAccount.authUser; |
293 |
self.authToken = selectedPithosAccount.authToken; |
294 |
} |
295 |
|
296 |
#pragma Sync Actions |
297 |
|
298 |
- (IBAction)syncApply:(id)sender { |
299 |
[selectedPithosAccount updateSyncWithSyncActive:syncActive |
300 |
syncDirectoryPath:syncDirectoryPath |
301 |
syncContainersDictionary:syncContainersDictionary]; |
302 |
[self updateSync]; |
303 |
pithos_macosAppDelegate *delegate = (pithos_macosAppDelegate *)[[NSApplication sharedApplication] delegate]; |
304 |
[delegate savePithosAccounts:self]; |
305 |
[delegate sync]; |
306 |
} |
307 |
|
308 |
- (IBAction)syncCancel:(id)sender { |
309 |
self.syncActive = selectedPithosAccount.syncActive; |
310 |
self.syncDirectoryPath = selectedPithosAccount.syncDirectoryPath; |
311 |
self.syncContainersDictionary = selectedPithosAccount.syncContainersDictionary; |
312 |
self.syncContainersRootFilesNodes = [NSMutableDictionary dictionary]; |
313 |
[self selectedPithosAccountNodeChildrenUpdated:nil]; |
314 |
} |
315 |
|
316 |
- (IBAction)syncRefresh:(id)sender { |
317 |
selectedPithosAccount.accountNode.forcedRefresh = YES; |
318 |
[selectedPithosAccount.accountNode invalidateChildrenRecursive]; |
319 |
if (selectedPithosAccount.accountNode.children) { |
320 |
} |
321 |
} |
322 |
|
323 |
#pragma mark Groups Actions |
324 |
|
325 |
- (IBAction)groupsApply:(id)sender { |
326 |
[[self window] makeFirstResponder:nil]; |
327 |
if (selectedPithosAccount.active) |
328 |
[selectedPithosAccount.accountNode applyInfo]; |
329 |
} |
330 |
|
331 |
- (IBAction)groupsRevert:(id)sender { |
332 |
if (selectedPithosAccount.active && selectedPithosAccount.accountNode) |
333 |
[selectedPithosAccount.accountNode refreshInfo]; |
334 |
} |
335 |
|
336 |
#pragma mark - |
337 |
#pragma mark NSOutlineViewDataSource |
338 |
|
339 |
- (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item { |
340 |
if (!selectedPithosAccount.active) |
341 |
return 0; |
342 |
if (outlineView == syncContainersOutlineView) { |
343 |
if (item == nil) { |
344 |
if (selectedPithosAccount.accountNode.children) |
345 |
return selectedPithosAccount.accountNode.children.count; |
346 |
} else if ([item class] == [PithosContainerNode class]) { |
347 |
// We add 1 for the root files node |
348 |
NSInteger subdirCount = 1; |
349 |
for (PithosNode *node in [(PithosContainerNode *)item children]) { |
350 |
if ([node class] == [PithosSubdirNode class]) |
351 |
subdirCount++; |
352 |
} |
353 |
return subdirCount; |
354 |
} |
355 |
} |
356 |
return 0; |
357 |
} |
358 |
|
359 |
- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item { |
360 |
if (outlineView == syncContainersOutlineView) { |
361 |
if (item == nil) |
362 |
return [selectedPithosAccount.accountNode.children objectAtIndex:index]; |
363 |
if ([item class] == [PithosContainerNode class]) { |
364 |
PithosContainerNode *containerNode = (PithosContainerNode *)item; |
365 |
NSInteger currentSubdirIndex = -1; |
366 |
for (PithosNode *node in containerNode.children) { |
367 |
if ([node class] == [PithosSubdirNode class]) { |
368 |
currentSubdirIndex++; |
369 |
if (currentSubdirIndex == index) |
370 |
return node; |
371 |
} |
372 |
} |
373 |
if (++currentSubdirIndex == index) { |
374 |
PithosEmptyNode *rootFilesNode = [syncContainersRootFilesNodes objectForKey:containerNode.displayName]; |
375 |
if (!rootFilesNode) { |
376 |
rootFilesNode = [[[PithosEmptyNode alloc] initWithDisplayName:@"<root files>" |
377 |
icon:[[NSWorkspace sharedWorkspace] iconForFileType:@""]] |
378 |
autorelease]; |
379 |
rootFilesNode.parent = containerNode; |
380 |
[syncContainersRootFilesNodes setObject:rootFilesNode forKey:containerNode.displayName]; |
381 |
} |
382 |
return rootFilesNode; |
383 |
} |
384 |
} |
385 |
} |
386 |
return nil; |
387 |
} |
388 |
|
389 |
- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item { |
390 |
if (outlineView == syncContainersOutlineView) { |
391 |
if ([item class] == [PithosContainerNode class]) |
392 |
return YES; |
393 |
} |
394 |
return NO; |
395 |
} |
396 |
|
397 |
- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item { |
398 |
if (outlineView == syncContainersOutlineView) { |
399 |
if ([[tableColumn identifier] isEqualToString:@"sync"]) { |
400 |
if ([item class] == [PithosContainerNode class]) { |
401 |
// A container is |
402 |
// off if not in dictionary |
403 |
// mixed if in dictionary with exclusions |
404 |
// on if in dictionary without exclusions |
405 |
PithosContainerNode *node = (PithosContainerNode *)item; |
406 |
NSMutableArray *containerExcludedDirectories = [syncContainersDictionary objectForKey:node.displayName]; |
407 |
if (containerExcludedDirectories) { |
408 |
if ([containerExcludedDirectories count]) |
409 |
return [NSNumber numberWithUnsignedInteger:NSMixedState]; |
410 |
else |
411 |
return [NSNumber numberWithUnsignedInteger:NSOnState]; |
412 |
} |
413 |
return [NSNumber numberWithUnsignedInteger:NSOffState]; |
414 |
} else if ([item class] == [PithosSubdirNode class]) { |
415 |
// Root files are off if parent container not in dictionary or if excluded |
416 |
// displayName should be localized and lowercased |
417 |
PithosSubdirNode *node = (PithosSubdirNode *)item; |
418 |
NSMutableArray *containerExcludedDirectories = [syncContainersDictionary objectForKey:node.parent.displayName]; |
419 |
NSString *directoryName = [[node.displayName lowercaseString] stringByReplacingOccurrencesOfString:@"/" withString:@":"]; |
420 |
if (!containerExcludedDirectories || [containerExcludedDirectories containsObject:directoryName]) |
421 |
return [NSNumber numberWithUnsignedInteger:NSOffState]; |
422 |
else |
423 |
return [NSNumber numberWithUnsignedInteger:NSOnState]; |
424 |
} else if ([item class] == [PithosEmptyNode class]) { |
425 |
// Root files are off if parent container not in dictionary or if excluded |
426 |
PithosEmptyNode *node = (PithosEmptyNode *)item; |
427 |
NSMutableArray *containerExcludedDirectories = [syncContainersDictionary objectForKey:node.parent.displayName]; |
428 |
if (!containerExcludedDirectories || [containerExcludedDirectories containsObject:@""]) |
429 |
return [NSNumber numberWithUnsignedInteger:NSOffState]; |
430 |
else |
431 |
return [NSNumber numberWithUnsignedInteger:NSOnState]; |
432 |
} |
433 |
return [NSNumber numberWithUnsignedInteger:NSOffState]; |
434 |
} else if ([[tableColumn identifier] isEqualToString:@"path"]) { |
435 |
return (PithosNode *)item; |
436 |
} |
437 |
} |
438 |
return nil; |
439 |
} |
440 |
|
441 |
- (void)outlineView:(NSOutlineView *)outlineView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn byItem:(id)item { |
442 |
if (outlineView == syncContainersOutlineView) { |
443 |
if ([[tableColumn identifier] isEqualToString:@"sync"]) { |
444 |
NSCellStateValue newState = [object unsignedIntegerValue]; |
445 |
if ([item class] == [PithosContainerNode class]) { |
446 |
// If new state is |
447 |
// mixed/on include container with no excluded directories |
448 |
// off exclude container |
449 |
PithosContainerNode *node = (PithosContainerNode *)item; |
450 |
if ((newState == NSOnState) || (newState == NSMixedState)) { |
451 |
[syncContainersDictionary setObject:[NSMutableArray array] forKey:node.displayName]; |
452 |
} else { |
453 |
[syncContainersDictionary removeObjectForKey:node.displayName]; |
454 |
} |
455 |
[outlineView reloadItem:item reloadChildren:YES]; |
456 |
} else if ([item class] == [PithosSubdirNode class]) { |
457 |
// If new state is |
458 |
// mixed/on include directory (if container not included, include and exclude all others) |
459 |
// off exclude directory |
460 |
PithosSubdirNode *node = (PithosSubdirNode *)item; |
461 |
NSMutableArray *containerExcludedDirectories = [syncContainersDictionary objectForKey:node.parent.displayName]; |
462 |
NSString *directoryName = [[node.displayName lowercaseString] stringByReplacingOccurrencesOfString:@"/" withString:@":"]; |
463 |
if ((newState == NSOnState) || (newState == NSMixedState)) { |
464 |
if (containerExcludedDirectories) { |
465 |
[containerExcludedDirectories removeObject:directoryName]; |
466 |
} else { |
467 |
NSMutableArray *newContainerExcludeDirectories = [NSMutableArray arrayWithObject:@""]; |
468 |
for (PithosNode *siblingNode in node.parent.children) { |
469 |
if ([siblingNode class] == [PithosSubdirNode class]) { |
470 |
NSString *siblingDirectoryName = [[siblingNode.displayName lowercaseString] stringByReplacingOccurrencesOfString:@"/" withString:@":"]; |
471 |
if (![siblingDirectoryName isEqualToString:directoryName] && |
472 |
![newContainerExcludeDirectories containsObject:siblingDirectoryName]) |
473 |
[newContainerExcludeDirectories addObject:siblingDirectoryName]; |
474 |
} |
475 |
} |
476 |
[syncContainersDictionary setObject:newContainerExcludeDirectories forKey:node.parent.displayName]; |
477 |
} |
478 |
} else if (![containerExcludedDirectories containsObject:directoryName]) { |
479 |
[containerExcludedDirectories addObject:directoryName]; |
480 |
} |
481 |
[outlineView reloadItem:[outlineView parentForItem:item]]; |
482 |
} else if ([item class] == [PithosEmptyNode class]) { |
483 |
// If new state is |
484 |
// mixed/on include root files (if container not included, include and exclude all others) |
485 |
// off exclude root files |
486 |
PithosEmptyNode *node = (PithosEmptyNode *)item; |
487 |
NSMutableArray *containerExcludedDirectories = [syncContainersDictionary objectForKey:node.parent.displayName]; |
488 |
if ((newState == NSOnState) || (newState == NSMixedState)) { |
489 |
if (containerExcludedDirectories) { |
490 |
[containerExcludedDirectories removeObject:@""]; |
491 |
} else { |
492 |
NSMutableArray *newContainerExcludeDirectories = [NSMutableArray array]; |
493 |
for (PithosNode *siblingNode in node.parent.children) { |
494 |
if ([siblingNode class] == [PithosSubdirNode class]) { |
495 |
NSString *siblingDirectoryName = [[siblingNode.displayName lowercaseString] stringByReplacingOccurrencesOfString:@"/" withString:@":"]; |
496 |
if (![newContainerExcludeDirectories containsObject:siblingDirectoryName]) |
497 |
[newContainerExcludeDirectories addObject:siblingDirectoryName]; |
498 |
} |
499 |
} |
500 |
[syncContainersDictionary setObject:newContainerExcludeDirectories forKey:node.parent.displayName]; |
501 |
} |
502 |
} else if (![containerExcludedDirectories containsObject:@""]) { |
503 |
[containerExcludedDirectories addObject:@""]; |
504 |
} |
505 |
[outlineView reloadItem:[outlineView parentForItem:item]]; |
506 |
} |
507 |
[self updateSync]; |
508 |
} |
509 |
} |
510 |
} |
511 |
|
512 |
@end |