#import "PithosContainerNode.h"
#import "PithosSubdirNode.h"
#import "PithosObjectNode.h"
+#import "PithosSharingAccountsNode.h"
#import "PithosEmptyNode.h"
#import "ImageAndTextCell.h"
#import "FileSystemBrowserCell.h"
- (void)resetContainers:(NSNotification *)notification {
rootNode = nil;
[browser loadColumnZero];
+ [containersNodeChildren removeAllObjects];
[outlineView reloadData];
-
// Expand the folder outline view
[outlineView expandItem:nil expandChildren:YES];
[outlineView selectRowIndexes:[NSIndexSet indexSetWithIndex:1] byExtendingSelection:NO];
// Refresh account
[accountNode refresh];
+ [mySharedNode refresh];
+ [othersSharedNode refresh];
}
- (void)windowDidLoad {
mySharedNode.displayName = @"my shared";
mySharedNode.shared = YES;
mySharedNode.icon = [[NSWorkspace sharedWorkspace] iconForFileType:NSFileTypeForHFSTypeCode(kUserIcon)];
- othersSharedNode = [[PithosEmptyNode alloc] initWithDisplayName:@"others shared"
- icon:[[NSWorkspace sharedWorkspace] iconForFileType:NSFileTypeForHFSTypeCode(kGroupIcon)]];
+ othersSharedNode = [[PithosSharingAccountsNode alloc] init];
+ othersSharedNode.displayName = @"others shared";
+ othersSharedNode.icon = [[NSWorkspace sharedWorkspace] iconForFileType:NSFileTypeForHFSTypeCode(kGroupIcon)];
[[[outlineView tableColumns] objectAtIndex:0] setDataCell:[[[PithosOutlineViewCell alloc] init] autorelease]];
// Register for updates
+ // PithosContainerNode updates browser nodes
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(pithosNodeChildrenUpdated:)
name:@"PithosContainerNodeChildrenUpdated"
object:nil];
+ // PithosSubdirNode updates browser nodes
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(pithosNodeChildrenUpdated:)
name:@"PithosSubdirNodeChildrenUpdated"
object:nil];
+ // PithosAccountNode accountNode updates outlineView container nodes
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(pithosAccountNodeChildrenUpdated:)
name:@"PithosAccountNodeChildrenUpdated"
object:accountNode];
+ // PithosAccountNode other than accountNode updates nodes
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(pithosNodeChildrenUpdated:)
name:@"PithosAccountNodeChildrenUpdated"
- object:mySharedNode];
+ object:nil];
+ // PithosSharingAccountsNode othersSharedNode updates browser nodes
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(pithosNodeChildrenUpdated:)
+ name:@"PithosSharingAccountsNodeChildrenUpdated"
+ object:othersSharedNode];
+ // Updated authentication credentials reset containers in the outline view
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(resetContainers:)
name:@"PithosAuthenticationCredentialsUpdated"
object:nil];
+ // Request for browser refresh
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(pithosBrowserRefreshNeeded:)
name:@"PithosBrowserRefreshNeeeded"
- (void)pithosNodeChildrenUpdated:(NSNotification *)notification {
PithosNode *node = (PithosNode *)[notification object];
+ if (node == accountNode)
+ return;
NSLog(@"pithosNodeChildrenUpdated:%@", node.url);
NSInteger lastColumn = [browser lastColumn];
for (NSInteger column = lastColumn; column >= 0; column--) {
// Expand the folder outline view
[outlineView expandItem:nil expandChildren:YES];
- if ((rootNode == containersNode) || (rootNode == sharedNode)) {
+ if ((rootNode == nil) || (rootNode == containersNode) || (rootNode == sharedNode)) {
rootNode = [containersNodeChildren objectAtIndex:0];
[browser loadColumnZero];
}
#pragma mark Actions
- (IBAction)refresh:(id)sender {
- if (sender)
- [accountNode refresh];
- for (NSInteger column = [browser lastColumn]; column >= 0; column--) {
- [(PithosNode *)[browser parentForItemsInColumn:column] invalidateChildren];
+ if ([[NSApp currentEvent] modifierFlags] & NSShiftKeyMask) {
+ if (sender)
+ [accountNode forceRefresh];
+ for (NSInteger column = [browser lastColumn]; column >= 0; column--) {
+ PithosNode *node = (PithosNode *)[browser parentForItemsInColumn:column];
+ node.forcedRefresh = YES;
+ [(PithosNode *)[browser parentForItemsInColumn:column] invalidateChildren];
+ //[(PithosNode *)[browser parentForItemsInColumn:column] forceRefresh];
+ }
+ } else {
+ if (sender)
+ [accountNode refresh];
+ for (NSInteger column = [browser lastColumn]; column >= 0; column--) {
+ [(PithosNode *)[browser parentForItemsInColumn:column] invalidateChildren];
+ }
}
[browser validateVisibleColumns];
}
- (BOOL)browser:(NSBrowser *)browser shouldEditItem:(id)item {
PithosNode *node = (PithosNode *)item;
- if (node.shared || ([node class] == [PithosContainerNode class]))
+ if (node.shared || node.sharingAccount ||
+ ([node class] == [PithosContainerNode class]) || ([node class] == [PithosAccountNode class]))
return NO;
return YES;
}
if ([PithosFileUtilities objectExistsAtContainerName:node.pithosContainer.name
objectName:destinationObjectName
error:&error
- isDirectory:&isDirectory]) {
+ isDirectory:&isDirectory
+ sharingAccount:nil]) {
NSAlert *alert = [[[NSAlert alloc] init] autorelease];
[alert setMessageText:@"Name Taken"];
[alert setInformativeText:[NSString stringWithFormat:@"The name '%@' is already taken. Please choose a different name", newName]];
if ([PithosFileUtilities objectExistsAtContainerName:node.pithosContainer.name
objectName:destinationObjectName
error:&error
- isDirectory:&isDirectory]) {
+ isDirectory:&isDirectory
+ sharingAccount:nil]) {
NSAlert *alert = [[[NSAlert alloc] init] autorelease];
[alert setMessageText:@"Name Taken"];
[alert setInformativeText:[NSString stringWithFormat:@"The name '%@' is already taken. Please choose a different name", newName]];
NSArray *objectRequests = [PithosFileUtilities objectDataRequestsForSubdirWithContainerName:node.pithosContainer.name
objectName:node.pithosObject.name
toDirectory:[dropDestination path]
- checkIfExists:YES];
+ checkIfExists:YES
+ sharingAccount:node.sharingAccount];
if (objectRequests) {
for (ASIPithosObjectRequest *objectRequest in objectRequests) {
[names addObject:[objectRequest.userInfo valueForKey:@"fileName"]];
ASIPithosObjectRequest *objectRequest = [PithosFileUtilities objectDataRequestWithContainerName:node.pithosContainer.name
objectName:node.pithosObject.name
toDirectory:[dropDestination path]
- checkIfExists:YES];
+ checkIfExists:YES
+ sharingAccount:node.sharingAccount];
if (objectRequest) {
[names addObject:[objectRequest.userInfo valueForKey:@"fileName"]];
objectRequest.delegate = self;
*row = -1;
// Only allow dropping in folders
if (*column != -1) {
+ PithosNode *dropNode;
if (*row != -1) {
// Check if the node is not a folder and if so redirect to the parent item
- if ([[browser itemAtRow:*row inColumn:*column] class] != [PithosSubdirNode class])
+ dropNode = [browser itemAtRow:*row inColumn:*column];
+ if ([dropNode class] == [PithosObjectNode class])
*row = -1;
}
- *dropOperation = NSBrowserDropOn;
- result = NSDragOperationCopy;
+ if (*row == -1)
+ dropNode = [browser parentForItemsInColumn:*column];
+
+ if (!dropNode.shared &&
+ (!dropNode.sharingAccount ||
+ ([dropNode class] == [PithosSubdirNode class]) ||
+ ([dropNode class] == [PithosContainerNode class]))) {
+ *dropOperation = NSBrowserDropOn;
+ result = NSDragOperationCopy;
+ }
}
} else if ([[[info draggingPasteboard] types] containsObject:NSFilesPromisePboardType]) {
// For a drop above, the drop is redirected to the parent item
if (*row != -1) {
// Check if the node is not a folder and if so redirect to the parent item
dropNode = [browser itemAtRow:*row inColumn:*column];
- if ([dropNode class] != [PithosSubdirNode class])
+ if ([dropNode class] == [PithosObjectNode class])
*row = -1;
}
if (*row == -1)
dropNode = [browser parentForItemsInColumn:*column];
- if (!dropNode.shared) {
+ if (!dropNode.shared && !dropNode.sharingAccount) {
if ([info draggingSourceOperationMask] & NSDragOperationMove) {
// NSDragOperationCopy | NSDragOperationMove -> NSDragOperationMove
if ((([dropNode class] == [PithosContainerNode class]) ||
blockHash:blockHash
forFile:filePath
checkIfExists:YES
- hashes:&hashes];
+ hashes:&hashes
+ sharingAccount:node.sharingAccount];
if (objectRequest) {
objectRequest.delegate = self;
objectRequest.didFinishSelector = @selector(uploadObjectUsingHashMapFinished:);
objectRequest.didFailSelector = @selector(uploadObjectUsingHashMapFailed:);
- objectRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
- containerName, @"containerName",
- objectName, @"objectName",
- contentType, @"contentType",
- [NSNumber numberWithUnsignedInteger:blockSize], @"blockSize",
- blockHash, @"blockHash",
- filePath, @"filePath",
- hashes, @"hashes",
- node, @"node",
- [NSNumber numberWithUnsignedInteger:10], @"iteration",
- nil];
+ NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
+ containerName, @"containerName",
+ objectName, @"objectName",
+ contentType, @"contentType",
+ [NSNumber numberWithUnsignedInteger:blockSize], @"blockSize",
+ blockHash, @"blockHash",
+ filePath, @"filePath",
+ hashes, @"hashes",
+ node, @"node",
+ [NSNumber numberWithUnsignedInteger:10], @"iteration",
+ nil];
+ if (node.sharingAccount)
+ [userInfo setObject:node.sharingAccount forKey:@"sharingAccount"];
+ objectRequest.userInfo = userInfo;
[objectRequest startAsynchronous];
}
});
contentTypes:&contentTypes
filePaths:&filePaths
hashesArrays:&hashesArrays
- directoryObjectRequests:&directoryObjectRequests];
+ directoryObjectRequests:&directoryObjectRequests
+ sharingAccount:node.sharingAccount];
for (ASIPithosObjectRequest *objectRequest in directoryObjectRequests) {
objectRequest.delegate = self;
objectRequest.didFinishSelector = @selector(uploadDirectoryObjectFinished:);
objectRequest.delegate = self;
objectRequest.didFinishSelector = @selector(uploadObjectUsingHashMapFinished:);
objectRequest.didFailSelector = @selector(uploadObjectUsingHashMapFailed:);
- objectRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
- containerName, @"containerName",
- [objectNames objectAtIndex:i], @"objectName",
- [contentTypes objectAtIndex:i], @"contentType",
- [NSNumber numberWithUnsignedInteger:blockSize], @"blockSize",
- blockHash, @"blockHash",
- [filePaths objectAtIndex:i], @"filePath",
- [hashesArrays objectAtIndex:i], @"hashes",
- [NSNumber numberWithUnsignedInteger:10], @"iteration",
- nil];
+ NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
+ containerName, @"containerName",
+ [objectNames objectAtIndex:i], @"objectName",
+ [contentTypes objectAtIndex:i], @"contentType",
+ [NSNumber numberWithUnsignedInteger:blockSize], @"blockSize",
+ blockHash, @"blockHash",
+ [filePaths objectAtIndex:i], @"filePath",
+ [hashesArrays objectAtIndex:i], @"hashes",
+ [NSNumber numberWithUnsignedInteger:10], @"iteration",
+ nil];
+ if (node.sharingAccount)
+ [userInfo setObject:node.sharingAccount forKey:@"sharingAccount"];
+ objectRequest.userInfo = userInfo;
[objectRequest startAsynchronous];
}
}
objectName:node.pithosObject.name
destinationContainerName:containerName
destinationObjectName:destinationObjectName
- checkIfExists:YES];
+ checkIfExists:YES
+ sharingAccount:nil];
if (objectRequest) {
objectRequest.delegate = self;
objectRequest.didFinishSelector = @selector(copyFinished:);
objectName:node.pithosObject.name
destinationContainerName:containerName
destinationObjectName:destinationObjectName
- checkIfExists:YES];
+ checkIfExists:YES
+ sharingAccount:nil];
if (objectRequests) {
for (ASIPithosObjectRequest *objectRequest in objectRequests) {
objectRequest.delegate = self;
objectName:@".upload"
blockSize:[[objectRequest.userInfo objectForKey:@"blockSize"] unsignedIntegerValue]
forFile:[objectRequest.userInfo objectForKey:@"filePath"]
- missingBlockIndex:missingBlockIndex];
+ missingBlockIndex:missingBlockIndex
+ sharingAccount:[objectRequest.userInfo objectForKey:@"sharingAccount"]];
newObjectRequest.delegate = self;
newObjectRequest.didFinishSelector = @selector(uploadMissingBlockFinished:);
newObjectRequest.didFailSelector = @selector(uploadMissingBlockFailed:);
blockHash:[objectRequest.userInfo objectForKey:@"blockHash"]
forFile:[objectRequest.userInfo objectForKey:@"filePath"]
checkIfExists:NO
- hashes:&hashes];
+ hashes:&hashes
+ sharingAccount:[objectRequest.userInfo objectForKey:@"sharingAccount"]];
newObjectRequest.delegate = self;
newObjectRequest.didFinishSelector = @selector(uploadObjectUsingHashMapFinished:);
newObjectRequest.didFailSelector = @selector(uploadObjectUsingHashMapFailed:);
objectName:@".upload"
blockSize:[[objectRequest.userInfo objectForKey:@"blockSize"] unsignedIntegerValue]
forFile:[objectRequest.userInfo objectForKey:@"filePath"]
- missingBlockIndex:missingBlockIndex];
+ missingBlockIndex:missingBlockIndex
+ sharingAccount:[objectRequest.userInfo objectForKey:@"sharingAccount"]];
newObjectRequest.delegate = self;
newObjectRequest.didFinishSelector = @selector(uploadMissingBlockFinished:);
newObjectRequest.didFailSelector = @selector(uploadMissingBlockFailed:);
} else {
menuNode = [browser itemAtIndexPath:[menuNodesIndexPaths objectAtIndex:0]];
}
- if ([menuNode class] == [PithosAccountNode class])
+ if (([menuNode class] == [PithosAccountNode class]) || ([menuNode class] == [PithosSharingAccountsNode class]))
return;
BOOL shared = menuNode.shared;
+ BOOL sharingAccount = (menuNode.sharingAccount != nil);
- if (!shared) {
+ if (!shared && !sharingAccount) {
// New Folder
menuItem = [[[NSMenuItem alloc] initWithTitle:@"New Folder" action:@selector(menuNewFolder:) keyEquivalent:@""] autorelease];
[menuItem setRepresentedObject:menuNode];
[menuItem setRepresentedObject:[NSArray arrayWithObject:menuNode]];
[menu addItem:menuItem];
- if (!shared) {
+ if (!shared && !sharingAccount) {
// Paste
if (clipboardNodes) {
NSUInteger clipboardNodesCount = [clipboardNodes count];
[menuNodes addObject:[browser itemAtIndexPath:clickedNodeIndexPath]];
}
NSUInteger menuNodesCount = [menuNodes count];
- BOOL shared = ((PithosNode *)[menuNodes objectAtIndex:0]).shared;
-
+ PithosNode *firstMenuNode = (PithosNode *)[menuNodes objectAtIndex:0];
+ BOOL shared = firstMenuNode.shared;
+ BOOL sharingAccount = (firstMenuNode.sharingAccount != nil);
- if (!shared) {
+ if (!shared && !sharingAccount) {
// Move to Trash (pithos container only)
// Delete
if ([rootNode class] == [PithosContainerNode class]) {
}
}
- // Get Info
- menuItem = [[[NSMenuItem alloc] initWithTitle:@"Get Info" action:@selector(menuGetInfo:) keyEquivalent:@""] autorelease];
- [menuItem setRepresentedObject:menuNodes];
- [menu addItem:menuItem];
-
- if (!shared || ([[menuNodes objectAtIndex:0] class] != [PithosContainerNode class]))
- [menu addItem:[NSMenuItem separatorItem]];
+ if (!sharingAccount || ([firstMenuNode class] != [PithosAccountNode class])) {
+ // Get Info
+ menuItem = [[[NSMenuItem alloc] initWithTitle:@"Get Info" action:@selector(menuGetInfo:) keyEquivalent:@""] autorelease];
+ [menuItem setRepresentedObject:menuNodes];
+ [menu addItem:menuItem];
+
+ if ((!shared && !sharingAccount) || ([firstMenuNode class] != [PithosContainerNode class]))
+ [menu addItem:[NSMenuItem separatorItem]];
+ }
- if (!shared) {
+ if (!shared && !sharingAccount) {
// Cut
if (menuNodesCount == 1)
[menu addItem:menuItem];
}
- if (!shared || ([[menuNodes objectAtIndex:0] class] != [PithosContainerNode class])) {
+ if ((!shared && !sharingAccount) ||
+ (([firstMenuNode class] != [PithosContainerNode class]) && ([firstMenuNode class] != [PithosAccountNode class]))) {
// Copy
if (menuNodesCount == 1)
menuItemTitle = [NSString stringWithFormat:@"Copy \"%@\"", ((PithosNode *)[menuNodes objectAtIndex:0]).displayName];
[menu addItem:menuItem];
}
- if (!shared) {
+ if (!shared && !sharingAccount) {
// Paste
if (menuNodesCount == 1) {
PithosNode *menuNode = [menuNodes objectAtIndex:0];
objectName:node.pithosObject.name
destinationContainerName:containerName
destinationObjectName:destinationObjectName
- checkIfExists:YES];
+ checkIfExists:YES
+ sharingAccount:node.sharingAccount];
if (objectRequest) {
objectRequest.delegate = self;
objectRequest.didFinishSelector = @selector(copyFinished:);
objectName:node.pithosObject.name
destinationContainerName:containerName
destinationObjectName:destinationObjectName
- checkIfExists:YES];
+ checkIfExists:YES
+ sharingAccount:node.sharingAccount];
if (objectRequests) {
for (ASIPithosObjectRequest *objectRequest in objectRequests) {
objectRequest.delegate = self;