Use NFC for local files that are uploaded. Fix menu labels. Update version.
[pithos-macos] / pithos-macos / PithosBrowserController.m
index fac1f5d..08812f3 100644 (file)
@@ -1099,7 +1099,8 @@ forDraggedRowsWithIndexes:(NSIndexSet *)rowIndexes inColumn:(NSInteger)column {
         if ([fileManager fileExistsAtPath:filePath isDirectory:&isDirectory]) {
             if (!isDirectory) {
                 // Upload file
-                NSString *objectName = [objectNamePrefix stringByAppendingPathComponent:[filePath lastPathComponent]];
+                NSString *objectName = [[objectNamePrefix stringByAppendingPathComponent:[filePath lastPathComponent]] 
+                                        precomposedStringWithCanonicalMapping];
                 // Operation: Upload a local file
                 __block NSOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
                     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
@@ -1176,7 +1177,8 @@ forDraggedRowsWithIndexes:(NSIndexSet *)rowIndexes inColumn:(NSInteger)column {
                 [alert addButtonWithTitle:@"Cancel"];
                 NSInteger choice = [alert runModal];
                 if (choice == NSAlertFirstButtonReturn) {
-                    NSString *objectName = [objectNamePrefix stringByAppendingPathComponent:[filePath lastPathComponent]];
+                    NSString *objectName = [[objectNamePrefix stringByAppendingPathComponent:[filePath lastPathComponent]] 
+                                            precomposedStringWithCanonicalMapping];
                     // Operation: Upload a local directory and its descendants
                     // The resulting ASIPithosObjectRequests are chained through dependencies
                     __block NSOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
@@ -2192,10 +2194,8 @@ forDraggedRowsWithIndexes:(NSIndexSet *)rowIndexes inColumn:(NSInteger)column {
             ([menuNode class] == [PithosSharingAccountsNode class]) ||
             ([menuNode class] == [PithosEmptyNode class]))
             return;
-        BOOL shared = menuNode.shared;
-        BOOL sharingAccount = (menuNode.sharingAccount != nil);
         // New Folder
-        if (!shared && !sharingAccount) {
+        if (!menuNode.shared && !menuNode.sharingAccount) {
             menuItem = [[[NSMenuItem alloc] initWithTitle:@"New Folder" action:@selector(menuNewFolder:) keyEquivalent:@""] autorelease];
             [menuItem setRepresentedObject:menuNode];
             [menu addItem:menuItem];
@@ -2212,49 +2212,48 @@ forDraggedRowsWithIndexes:(NSIndexSet *)rowIndexes inColumn:(NSInteger)column {
         [menuItem setRepresentedObject:[NSArray arrayWithObject:menuNode]];
         [menu addItem:menuItem];
         // Paste
-        if (!shared && !sharingAccount) {
-            if (clipboardNodes) {
-                NSUInteger clipboardNodesCount = [clipboardNodes count];
-                if (clipboardNodesCount == 0) {
-                    self.clipboardNodes = nil;
-                } else if (clipboardCopy || ![menuNode isEqualTo:clipboardParentNode]) {
-                    if (clipboardNodesCount == 1)
-                        menuItemTitle = [NSString stringWithString:@"Paste Item"];
-                    else
-                        menuItemTitle = [NSString stringWithString:@"Paste Items"];
-                    [menu addItem:[NSMenuItem separatorItem]];
-                    menuItem = [[[NSMenuItem alloc] initWithTitle:menuItemTitle action:@selector(menuPaste:) keyEquivalent:@""] autorelease];
-                    [menuItem setRepresentedObject:menuNode];
-                    [menu addItem:menuItem];
-                }
+        if (clipboardNodes && !menuNode.shared && !menuNode.sharingAccount && 
+            (([menuNode class] == [PithosContainerNode class]) || 
+             (([menuNode class] == [PithosSubdirNode class]) && 
+              (menuNode.pithosObject.subdir || ![menuNode.pithosObject.name hasSuffix:@"/"])))) {
+            NSUInteger clipboardNodesCount = [clipboardNodes count];
+            if (clipboardNodesCount == 0) {
+                self.clipboardNodes = nil;
+            } else if (clipboardCopy || ![menuNode isEqualTo:clipboardParentNode]) {
+                if (clipboardNodesCount == 1)
+                    menuItemTitle = [NSString stringWithString:@"Paste Item"];
+                else
+                    menuItemTitle = [NSString stringWithString:@"Paste Items"];
+                [menu addItem:[NSMenuItem separatorItem]];
+                menuItem = [[[NSMenuItem alloc] initWithTitle:menuItemTitle action:@selector(menuPaste:) keyEquivalent:@""] autorelease];
+                [menuItem setRepresentedObject:menuNode];
+                [menu addItem:menuItem];
             }
         }
     } else {
         // Node context menu
         NSUInteger menuNodesCount = [menuNodes count];
-        PithosNode *firstMenuNode = (PithosNode *)[menuNodes objectAtIndex:0];
-        BOOL shared = firstMenuNode.shared;
-        BOOL sharingAccount = (firstMenuNode.sharingAccount != nil);
+        PithosNode *firstMenuNode = [menuNodes objectAtIndex:0];
         // Move to Trash (pithos container only)
         // Delete
-        if (!shared && !sharingAccount) {
-            if ([rootNode class] == [PithosContainerNode class]) {
-                if ([rootNode.pithosContainer.name isEqualToString:@"pithos"]) {
-                    menuItem = [[[NSMenuItem alloc] initWithTitle:@"Move to Trash" action:@selector(menuMoveToTrash:) keyEquivalent:@""] autorelease];
-                    [menuItem setRepresentedObject:menuNodes];
-                    [menu addItem:menuItem];
-                }
-                menuItem = [[[NSMenuItem alloc] initWithTitle:@"Delete" action:@selector(menuDelete:) keyEquivalent:@""] autorelease];
+        if (!firstMenuNode.shared && !firstMenuNode.sharingAccount && ([rootNode class] == [PithosContainerNode class])) {
+            if ([rootNode.pithosContainer.name isEqualToString:@"pithos"]) {
+                menuItem = [[[NSMenuItem alloc] initWithTitle:@"Move to Trash" 
+                                                       action:@selector(menuMoveToTrash:) 
+                                                keyEquivalent:@""] autorelease];
                 [menuItem setRepresentedObject:menuNodes];
                 [menu addItem:menuItem];
-                [menu addItem:[NSMenuItem separatorItem]];
             }
+            menuItem = [[[NSMenuItem alloc] initWithTitle:@"Delete" action:@selector(menuDelete:) keyEquivalent:@""] autorelease];
+            [menuItem setRepresentedObject:menuNodes];
+            [menu addItem:menuItem];
+            [menu addItem:[NSMenuItem separatorItem]];
         }
         // Refresh
         menuItem = [[[NSMenuItem alloc] initWithTitle:@"Refresh" action:@selector(refresh:) keyEquivalent:@""] autorelease];
         [menu addItem:menuItem];
         // Get Info
-        if (!sharingAccount || ([firstMenuNode class] != [PithosAccountNode class])) {
+        if (!firstMenuNode.sharingAccount || ([firstMenuNode class] != [PithosAccountNode class])) {
             [menu addItem:[NSMenuItem separatorItem]];
             menuItem = [[[NSMenuItem alloc] initWithTitle:(([firstMenuNode class] == [PithosContainerNode class]) ? @"Info" : @"Info and Sharing") 
                                                    action:@selector(menuGetInfo:) 
@@ -2262,11 +2261,11 @@ forDraggedRowsWithIndexes:(NSIndexSet *)rowIndexes inColumn:(NSInteger)column {
             [menuItem setRepresentedObject:menuNodes];
             [menu addItem:menuItem];
             
-            if ((!shared && !sharingAccount) || ([firstMenuNode class] != [PithosContainerNode class]))
+            if ((!firstMenuNode.shared && !firstMenuNode.sharingAccount) || ([firstMenuNode class] != [PithosContainerNode class]))
                 [menu addItem:[NSMenuItem separatorItem]];
         }
         // Cut
-        if (!shared && !sharingAccount) {
+        if (!firstMenuNode.shared && !firstMenuNode.sharingAccount) {
             if (menuNodesCount == 1)
                 menuItemTitle = [NSString stringWithFormat:@"Cut \"%@\"", ((PithosNode *)[menuNodes objectAtIndex:0]).displayName];
             else 
@@ -2276,7 +2275,7 @@ forDraggedRowsWithIndexes:(NSIndexSet *)rowIndexes inColumn:(NSInteger)column {
             [menu addItem:menuItem];
         }
         // Copy
-        if ((!shared && !sharingAccount) || 
+        if ((!firstMenuNode.shared && !firstMenuNode.sharingAccount) || 
             (([firstMenuNode class] != [PithosContainerNode class]) && ([firstMenuNode class] != [PithosAccountNode class]))) {
             if (menuNodesCount == 1)
                 menuItemTitle = [NSString stringWithFormat:@"Copy \"%@\"", ((PithosNode *)[menuNodes objectAtIndex:0]).displayName];
@@ -2287,32 +2286,94 @@ forDraggedRowsWithIndexes:(NSIndexSet *)rowIndexes inColumn:(NSInteger)column {
             [menu addItem:menuItem];
         }
         // Paste
-        if (!shared && !sharingAccount) {
-            if (menuNodesCount == 1) {
-                PithosNode *menuNode = [menuNodes objectAtIndex:0];
-                if (([menuNode class] == [PithosSubdirNode class]) && 
-                    (menuNode.pithosObject.subdir || ![menuNode.pithosObject.name hasSuffix:@"/"])) {
-                    if (clipboardNodes) {
-                        NSUInteger clipboardNodesCount = [clipboardNodes count];
-                        if (clipboardNodesCount == 0) {
-                            self.clipboardNodes = nil;
-                        } else if (clipboardCopy || ![menuNode isEqualTo:clipboardParentNode]) {
-                            if (clipboardNodesCount == 1)
-                                menuItemTitle = [NSString stringWithString:@"Paste Item"];
-                            else
-                                menuItemTitle = [NSString stringWithString:@"Paste Items"];
-                            menuItem = [[[NSMenuItem alloc] initWithTitle:menuItemTitle action:@selector(menuPaste:) keyEquivalent:@""] autorelease];
-                            [menuItem setRepresentedObject:menuNode];
-                            [menu addItem:menuItem];
-                        }
-                    }
-                }
+        if (clipboardNodes && !firstMenuNode.shared && !firstMenuNode.sharingAccount && (menuNodesCount == 1) && 
+            ([firstMenuNode class] == [PithosSubdirNode class]) && 
+            (firstMenuNode.pithosObject.subdir || ![firstMenuNode.pithosObject.name hasSuffix:@"/"])) {
+            NSUInteger clipboardNodesCount = [clipboardNodes count];
+            if (clipboardNodesCount == 0) {
+                self.clipboardNodes = nil;
+            } else if (clipboardCopy || ![firstMenuNode isEqualTo:clipboardParentNode]) {
+                if (clipboardNodesCount == 1)
+                    menuItemTitle = [NSString stringWithString:@"Paste Item"];
+                else
+                    menuItemTitle = [NSString stringWithString:@"Paste Items"];
+                menuItem = [[[NSMenuItem alloc] initWithTitle:menuItemTitle action:@selector(menuPaste:) keyEquivalent:@""] autorelease];
+                [menuItem setRepresentedObject:firstMenuNode];
+                [menu addItem:menuItem];
             }
         }
     }
 }
 
 #pragma mark -
+#pragma mark NSMenuValidation
+
+- (BOOL)validateMenuItem:(NSMenuItem *)menuItem {
+    if ((menuItem.action == @selector(cut:)) || (menuItem.action == @selector(copy:)) || (menuItem.action == @selector(delete:))) {
+        NSArray *menuNodesIndexPaths = [browser selectionIndexPaths];
+        if ([menuNodesIndexPaths count] == 0)
+            return NO;
+        
+        PithosNode *firstMenuNode = [browser itemAtIndexPath:[menuNodesIndexPaths objectAtIndex:0]];
+        if (((menuItem.action == @selector(cut:)) && (firstMenuNode.shared || firstMenuNode.sharingAccount)) || 
+            ((menuItem.action == @selector(copy:)) && (firstMenuNode.shared || firstMenuNode.sharingAccount) && 
+             (([firstMenuNode class] == [PithosContainerNode class]) || ([firstMenuNode class] == [PithosAccountNode class]))) ||
+            ((menuItem.action == @selector(delete:)) && 
+             (firstMenuNode.shared || firstMenuNode.sharingAccount || ([rootNode class] != [PithosContainerNode class]) || 
+              ((menuItem.tag == 0) && ![rootNode.pithosContainer.name isEqualToString:@"pithos"]))))
+            return NO;
+        
+        NSMutableArray *menuNodes = [NSMutableArray arrayWithCapacity:[menuNodesIndexPaths count]];
+        for (NSIndexPath *nodeIndexPath in menuNodesIndexPaths) {
+            [menuNodes addObject:[browser itemAtIndexPath:nodeIndexPath]];
+        }
+        menuItem.representedObject = menuNodes;
+    } else if (menuItem.action == @selector(paste:)) {
+        if (!clipboardNodes || ![clipboardNodes count])
+            return NO;
+        
+        NSArray *menuNodesIndexPaths = [browser selectionIndexPaths];
+        PithosNode *menuNode;
+        if ([menuNodesIndexPaths count] == 0)
+            menuNode = [browser parentForItemsInColumn:0];
+        else if (([menuNodesIndexPaths count] != 1) || 
+                 ([[browser itemAtIndexPath:[menuNodesIndexPaths objectAtIndex:0]] class] == [PithosObjectNode class]))
+            menuNode = [browser parentForItemsInColumn:([[menuNodesIndexPaths objectAtIndex:0] length] - 1)];
+        else
+            menuNode = [browser itemAtIndexPath:[menuNodesIndexPaths objectAtIndex:0]];
+        
+        if (menuNode.shared || menuNode.sharingAccount || 
+            (([menuNode class] != [PithosContainerNode class]) && 
+             (([menuNode class] != [PithosSubdirNode class]) || 
+              (!menuNode.pithosObject.subdir && [menuNode.pithosObject.name hasSuffix:@"/"]))) || 
+            (!clipboardCopy && [menuNode isEqualTo:clipboardParentNode]))
+            return NO;
+
+        menuItem.representedObject = menuNode;
+    }
+    return YES;
+}
+
+- (void)cut:(NSMenuItem *)sender {
+    [self menuCut:sender];
+}
+
+- (void)copy:(NSMenuItem *)sender {
+    [self menuCopy:sender];
+}
+
+- (void)paste:(NSMenuItem *)sender {
+    [self menuPaste:sender];
+}
+
+- (void)delete:(NSMenuItem *)sender {
+    if (sender.tag == 0)
+        [self menuMoveToTrash:sender];
+    else
+        [self menuDelete:sender];
+}
+
+#pragma mark -
 #pragma mark Menu Actions
 
 - (void)menuNewFolder:(NSMenuItem *)sender {
@@ -2665,12 +2726,12 @@ forDraggedRowsWithIndexes:(NSIndexSet *)rowIndexes inColumn:(NSInteger)column {
         return;
     PithosNode *dropNode = (PithosNode *)[sender representedObject];
     NSArray *localClipboardNodes = [NSArray arrayWithArray:clipboardNodes];
-    if (!clipboardCopy && ![dropNode isEqualTo:clipboardParentNode]) {
+    if (clipboardCopy) {
+        [self copyNodes:localClipboardNodes toNode:dropNode];
+    } else if (![dropNode isEqualTo:clipboardParentNode]) {
         self.clipboardNodes = nil;
         self.clipboardParentNode = nil;
         [self moveNodes:localClipboardNodes toNode:dropNode];
-    } else {
-        [self copyNodes:localClipboardNodes toNode:dropNode];
     }
 }