2 // PithosBrowserController.m
5 // Copyright 2011 GRNET S.A. All rights reserved.
7 // Redistribution and use in source and binary forms, with or
8 // without modification, are permitted provided that the following
11 // 1. Redistributions of source code must retain the above
12 // copyright notice, this list of conditions and the following
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.
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.
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.
38 #import "PithosBrowserController.h"
39 #import "ASIPithosRequest.h"
40 #import "PithosAccount.h"
41 #import "PithosContainer.h"
42 #import "PithosEmpty.h"
43 #import "ImageAndTextCell.h"
45 @interface PithosBrowserCell : NSBrowserCell {}
48 @implementation PithosBrowserCell
50 - (void)setObjectValue:(id)object {
51 if ([object isKindOfClass:[PithosNode class]]) {
52 PithosNode *node = (PithosNode *)object;
53 [self setStringValue:node.displayName];
54 [self setImage:node.icon];
55 // All cells are set as leafs because a branchingImage is already set!
56 // Maybe this cell is already inside an NSBrowserCell
59 [super setObjectValue:object];
65 @interface PithosOutlineViewCell : ImageAndTextCell {}
68 @implementation PithosOutlineViewCell
70 - (void)setObjectValue:(id)object {
71 if ([object isKindOfClass:[PithosNode class]]) {
72 PithosNode *node = (PithosNode *)object;
73 [self setStringValue:node.displayName];
74 [self setImage:node.icon];
75 [self setEditable:NO];
77 [super setObjectValue:object];
83 @interface PithosBrowserController (Private) {}
85 - (void)resetContainers;
88 @implementation PithosBrowserController
89 @synthesize userDefaultsController, outlineViewDataSourceArray, splitView, outlineView, browser, authenticationPanel;
92 #pragma Object Lifecycle
95 return [super initWithWindowNibName:@"PithosBrowserController"];
99 [[NSNotificationCenter defaultCenter] removeObserver:self];
100 [outlineViewDataSourceArray release];
102 [authenticationPanel release];
105 [outlineView release];
106 [userDefaultsController release];
110 - (void)awakeFromNib {
111 [browser setCellClass:[PithosBrowserCell class]];
114 - (void)resetContainers {
116 [browser loadColumnZero];
117 self.outlineViewDataSourceArray = nil;
119 // Create the outlineView tree
120 NSTreeNode *treeNode = [NSTreeNode treeNodeWithRepresentedObject:
121 [[[PithosEmpty alloc] initWithDisplayName:@"CONTAINERS" icon:nil] autorelease]];
122 [[treeNode mutableChildNodes] addObject:
123 [NSTreeNode treeNodeWithRepresentedObject:
124 [[[PithosContainer alloc] initWithContainerName:@"pithos"] autorelease]]];
125 [[treeNode mutableChildNodes] addObject:
126 [NSTreeNode treeNodeWithRepresentedObject:
127 [[[PithosContainer alloc] initWithContainerName:@"trash"] autorelease]]];
129 self.outlineViewDataSourceArray = [NSMutableArray arrayWithObject:treeNode];
131 // Expand the folder outline view
132 [outlineView expandItem:nil expandChildren:YES];
133 [outlineView selectRowIndexes:[NSIndexSet indexSetWithIndex:1] byExtendingSelection:NO];
136 - (void)windowDidLoad {
137 // [userDefaultsController setAppliesImmediately:NO];
139 [[[outlineView tableColumns] objectAtIndex:0] setDataCell:[[[PithosOutlineViewCell alloc] init] autorelease]];
141 // Register for updates
142 [[NSNotificationCenter defaultCenter] addObserver:self
143 selector:@selector(pithosNodeChildrenUpdated:)
144 name:@"PithosNodeChildrenUpdated"
153 - (void)pithosNodeChildrenUpdated:(NSNotification *)notification {
154 if ([[browser parentForItemsInColumn:[browser lastColumn]] isEqualTo:[notification object]])
155 [browser reloadColumn:[browser lastColumn]];
161 - (IBAction)refresh:(id)sender {
162 [[browser parentForItemsInColumn:[browser lastColumn]] invalidateChildren];
163 [browser reloadColumn:[browser lastColumn]];
167 #pragma Authentication
169 - (void)authenticate {
170 NSString *authURL = [[userDefaultsController values] valueForKey:@"authURL"];
171 NSString *username = [[userDefaultsController values] valueForKey:@"username"];
172 NSString *apiKey = [[userDefaultsController values] valueForKey:@"apiKey"];
173 NSString *storageURL = [[userDefaultsController values] valueForKey:@"storageURL"];
174 NSString *authToken = [[userDefaultsController values] valueForKey:@"authToken"];
176 NSLog(@"Authentication - authURL:%@, username:%@, apiKey:%@, storageURL:%@, authToken:%@", authURL, username, apiKey, storageURL, authToken);
177 if (storageURL && authToken) {
178 [ASIPithosRequest setStorageURL:storageURL];
179 [ASIPithosRequest setAuthToken:authToken];
180 [self resetContainers];
181 } else if (authURL && username && apiKey) {
182 [ASIPithosRequest setAuthURL:authURL];
183 [ASIPithosRequest setUsername:username];
184 [ASIPithosRequest setApiKey:apiKey];
185 NSError *error = [ASIPithosRequest authenticate];
187 // XXX Do something on error.
188 NSLog(@"error:%@", error);
190 [[userDefaultsController values] setValue:[ASIPithosRequest storageURL] forKey:@"storageURL"];
191 [[userDefaultsController values] setValue:[ASIPithosRequest authToken] forKey:@"authToken"];
192 [userDefaultsController save:nil];
194 [self resetContainers];
196 [self authenticationSelect:nil];
200 - (IBAction)authenticationSelect:(id)sender {
201 [self.window makeFirstResponder:nil];
203 [NSApp beginSheet:authenticationPanel
204 modalForWindow:self.window
210 - (IBAction)authenticationDone:(id)sender {
211 [NSApp endSheet:authenticationPanel];
212 [authenticationPanel orderOut:self];
213 [userDefaultsController save:sender];
217 - (IBAction)authenticationCancel:(id)sender {
218 [NSApp endSheet:authenticationPanel];
219 [authenticationPanel orderOut:self];
220 [userDefaultsController revert:sender];
224 #pragma NSBrowserDelegate
226 - (id)rootItemForBrowser:(NSBrowser *)browser {
230 - (NSInteger)browser:(NSBrowser *)browser numberOfChildrenOfItem:(id)item {
231 PithosNode *node = (PithosNode *)item;
232 return node.children.count;
235 - (id)browser:(NSBrowser *)browser child:(NSInteger)index ofItem:(id)item {
236 PithosNode *node = (PithosNode *)item;
237 return [node.children objectAtIndex:index];
240 - (BOOL)browser:(NSBrowser *)browser isLeafItem:(id)item {
241 PithosNode *node = (PithosNode *)item;
242 return node.isLeafItem;
245 - (id)browser:(NSBrowser *)browser objectValueForItem:(id)item {
246 PithosNode *node = (PithosNode *)item;
251 #pragma NSSplitViewDelegate
253 - (CGFloat)splitView:(NSSplitView *)splitView constrainMinCoordinate:(CGFloat)proposedMinimumPosition ofSubviewAt:(NSInteger)dividerIndex {
257 - (CGFloat)splitView:(NSSplitView *)splitView constrainMaxCoordinate:(CGFloat)proposedMaximumPosition ofSubviewAt:(NSInteger)dividerIndex {
262 #pragma mark NSOutlineViewDelegate
264 - (BOOL)outlineView:outlineView shouldSelectItem:(id)item {
265 return ([[item representedObject] isLeaf]);
268 - (BOOL)outlineView:(NSOutlineView *)outlineView isGroupItem:(id)item {
269 return (![[item representedObject] isLeaf]);
272 - (void)outlineViewSelectionDidChange:(NSNotification *)notification {
273 PithosNode *node = [[[outlineView itemAtRow:[outlineView selectedRow]] representedObject] representedObject];
276 [browser loadColumnZero];