Implemented menu delete and move to trash.
[pithos-macos] / pithos-macos / PithosBrowserController.m
index 8452bbc..55a1c9f 100644 (file)
@@ -51,7 +51,6 @@
 #import "ASIPithosObject.h"
 #import "PithosFileUtilities.h"
 
-//@interface PithosBrowserCell : NSBrowserCell {}
 @interface PithosBrowserCell : FileSystemBrowserCell {}
 @end
 
@@ -69,9 +68,6 @@
         PithosNode *node = (PithosNode *)object;
         [self setStringValue:node.displayName];
         [self setImage:node.icon];
-//        // All cells are set as leafs because a branchingImage is already set!
-//        // Maybe this cell is already inside an NSBrowserCell
-//        [self setLeaf:YES];
     } else {
         [super setObjectValue:object];
     }
@@ -98,7 +94,7 @@
 @end
 
 @interface PithosBrowserController (Private) {}
-- (void)resetContainers;
+- (void)resetContainers:(NSNotification *)notification;
 - (void)getInfo:(NSMenuItem *)sender;
 - (void)downloadObjectFinished:(ASIPithosObjectRequest *)objectRequest;
 - (void)downloadObjectFailed:(ASIPithosObjectRequest *)objectRequest;
     [browser setMenu:browserMenu];
 }
 
-- (void)resetContainers {
+- (void)resetContainers:(NSNotification *)notification {
     rootNode = nil;
     [browser loadColumnZero];
     self.outlineViewDataSourceArray = nil;
     // CONTAINERS
        NSTreeNode *containersTreeNode = [NSTreeNode treeNodeWithRepresentedObject:
                             [[[PithosEmptyNode alloc] initWithDisplayName:@"CONTAINERS" icon:nil] autorelease]];
-//    // CONTAINERS/pithos
-//     [[containersTreeNode mutableChildNodes] addObject:
-//     [NSTreeNode treeNodeWithRepresentedObject:
-//      [[[PithosContainerNode alloc] initWithContainerName:@"pithos" 
-//                                                     icon:[[NSWorkspace sharedWorkspace] iconForFileType:NSFileTypeForHFSTypeCode(kToolbarHomeIcon)]
-//        ] autorelease]]];
-//    // CONTAINERS/trash
-//     [[containersTreeNode mutableChildNodes] addObject:
-//     [NSTreeNode treeNodeWithRepresentedObject:
-//      [[[PithosContainerNode alloc] initWithContainerName:@"trash"
-//                                                     icon:[[NSWorkspace sharedWorkspace] iconForFileType:NSFileTypeForHFSTypeCode(kFullTrashIcon)]
-//        ] autorelease]]];
+
     // SHARED
        NSTreeNode *sharedTreeNode = [NSTreeNode treeNodeWithRepresentedObject:
                                       [[[PithosEmptyNode alloc] initWithDisplayName:@"SHARED" icon:nil] autorelease]];
                                                  name:@"PithosAccountNodeChildrenUpdated" 
                                                object:nil];
     [[NSNotificationCenter defaultCenter] addObserver:self 
-                                             selector:@selector(resetContainers) 
+                                             selector:@selector(resetContainers:) 
                                                  name:@"PithosAuthenticationCredentialsUpdated" 
                                                object:nil];
 }
 
 - (void)pithosNodeChildrenUpdated:(NSNotification *)notification {
     PithosNode *node = (PithosNode *)[notification object];
+    NSLog(@"pithosNodeChildrenUpdated:%@", node.url);
     NSInteger lastColumn = [browser lastColumn];
     for (NSInteger column = lastColumn; column >= 0; column--) {
         if ([[browser parentForItemsInColumn:column] isEqualTo:node]) {
             [browser reloadColumn:column];
-            if ((column == lastColumn - 1) && ([[browser parentForItemsInColumn:lastColumn] isLeafItem])) {
-                // This reloads the preview column
-                [browser setLastColumn:column];
-                [browser addColumn];
-            }
+            // The following code is unnecessary since the pithosObject is set in the PithosNode in each refresh
+            // Furthermore it caused problems on delete, because a non-existing parent was asked for
+            //if ((column == lastColumn - 1) && ([[browser parentForItemsInColumn:lastColumn] isLeafItem])) {
+            //    // This reloads the preview column
+            //    [browser setLastColumn:column];
+            //    [browser addColumn];
+            //}
             return;
         }
     }
 - (void)pithosAccountNodeChildrenUpdated:(NSNotification *)notification {
     BOOL containerPithosFound = NO;
     BOOL containerTrashFound = NO;
-    //NSMutableArray *containersTreeNodeChildren = [[outlineViewDataSourceArray objectAtIndex:0] mutableChildNodes];
     NSMutableArray *containersTreeNodeChildren = [NSMutableArray array];
     for (PithosContainerNode *containerNode in accountNode.children) {
         if ([containerNode.pithosContainer.name isEqualToString:@"pithos"]) {
         ASIPithosContainerRequest *containerRequest = [ASIPithosContainerRequest createOrUpdateContainerRequestWithContainerName:@"pithos"];
         [containerRequest startSynchronous];
         if ([containerRequest error]) {
-            NSLog(@"error:%@", [containerRequest error]);
-            // XXX do something on error
+            [PithosFileUtilities httpRequestErrorAlertWithRequest:containerRequest];
         } else {
             refreshAccountNode = YES;
         }
         ASIPithosContainerRequest *containerRequest = [ASIPithosContainerRequest createOrUpdateContainerRequestWithContainerName:@"trash"];
         [containerRequest startSynchronous];
         if ([containerRequest error]) {
-            NSLog(@"error:%@", [containerRequest error]);
-            // XXX do something on error
+            [PithosFileUtilities httpRequestErrorAlertWithRequest:containerRequest];
         } else {
             refreshAccountNode = YES;
         }
@@ -422,7 +407,7 @@ forDraggedRowsWithIndexes:(NSIndexSet *)rowIndexes inColumn:(NSInteger)column {
              dropOperation:(NSBrowserDropOperation *)dropOperation {
     NSDragOperation result = NSDragOperationNone;
     // Files from the finder are accepted
-    if ([[[info draggingPasteboard] types] indexOfObject:NSFilenamesPboardType] != -1) {
+    if ([[[info draggingPasteboard] types] containsObject:NSFilenamesPboardType]) {
         // For a between drop, we let the user drop "on" the parent item
         if (*dropOperation == NSBrowserDropAbove)
             *row = -1;
@@ -715,6 +700,7 @@ forDraggedRowsWithIndexes:(NSIndexSet *)rowIndexes inColumn:(NSInteger)column {
     if (node) {
         rootNode = node;
         [browser loadColumnZero];
+        [self refresh:nil];                                  
     }
 }
 
@@ -725,12 +711,25 @@ forDraggedRowsWithIndexes:(NSIndexSet *)rowIndexes inColumn:(NSInteger)column {
     NSInteger column = [browser clickedColumn];
     NSInteger row = [browser clickedRow];
     [menu removeAllItems];
+    NSMenuItem *menuItem;
     if ((column == -1) || (row == -1)) {
-        // General context menu has 0
+        // General context menu
     } else {
-        // PithosNode menu has 1 items
+        // Move to Trash (pithos container only)
+        // Delete
+        if ([rootNode class] == [PithosContainerNode class]) {
+            if ([rootNode.pithosContainer.name isEqualToString:@"pithos"]) {
+                menuItem = [[[NSMenuItem alloc] initWithTitle:@"Move to Trash" action:@selector(moveToTrash:) keyEquivalent:@""] autorelease];
+                [menuItem setRepresentedObject:[browser itemAtRow:row inColumn:column]];
+                [menu addItem:menuItem];
+            }
+            menuItem = [[[NSMenuItem alloc] initWithTitle:@"Delete" action:@selector(deleteObject:) keyEquivalent:@""] autorelease];
+            [menuItem setRepresentedObject:[browser itemAtRow:row inColumn:column]];
+            [menu addItem:menuItem];
+            [menu addItem:[NSMenuItem separatorItem]];
+        }
         // Get Info
-        NSMenuItem *menuItem = [[NSMenuItem alloc] initWithTitle:@"Get Info" action:@selector(getInfo:) keyEquivalent:@""];
+        menuItem = [[[NSMenuItem alloc] initWithTitle:@"Get Info" action:@selector(getInfo:) keyEquivalent:@""] autorelease];
         [menuItem setRepresentedObject:[browser itemAtRow:row inColumn:column]];
         [menu addItem:menuItem];
     }
@@ -743,4 +742,108 @@ forDraggedRowsWithIndexes:(NSIndexSet *)rowIndexes inColumn:(NSInteger)column {
     [(PithosNode *)[sender representedObject] showPithosNodeInfo:sender];
 }
 
+- (void)deleteObject:(NSMenuItem *)sender {
+    PithosNode *node = (PithosNode *)[sender representedObject];
+    if (([node class] == [PithosObjectNode class]) || 
+        (([node class] == [PithosSubdirNode class]) && 
+         !node.pithosObject.subdir &&
+         [node.pithosObject.name hasSuffix:@"/"])) {
+        ASIPithosObjectRequest *objectRequest = [ASIPithosObjectRequest deleteObjectRequestWithContainerName:node.pithosContainer.name 
+                                                                                                  objectName:node.pithosObject.name];
+        objectRequest.delegate = self;
+        objectRequest.didFinishSelector = @selector(deleteObjectFinished:);
+        objectRequest.didFailSelector = @selector(deleteObjectFailed:);
+        [objectRequest startAsynchronous];
+    } else if ([node class] == [PithosSubdirNode class]) {
+        NSArray *objectRequests = [PithosFileUtilities deleteObjectRequestsForSubdirWithContainerName:node.pithosContainer.name 
+                                                                                           objectName:node.pithosObject.name];
+        if (objectRequests) {
+            for (ASIPithosObjectRequest *objectRequest in objectRequests) {
+                objectRequest.delegate = self;
+                objectRequest.didFinishSelector = @selector(deleteObjectFinished:);
+                objectRequest.didFailSelector = @selector(deleteObjectFailed:);
+                [objectRequest startAsynchronous];
+            }
+        }
+        
+    }    
+}
+
+- (void)moveToTrash:(NSMenuItem *)sender {
+    PithosNode *node = (PithosNode *)[sender representedObject];
+    if (([node class] == [PithosObjectNode class]) || 
+        (([node class] == [PithosSubdirNode class]) && 
+         !node.pithosObject.subdir &&
+         [node.pithosObject.name hasSuffix:@"/"])) {
+        NSString *safeObjectName = [PithosFileUtilities safeObjectNameForContainerName:@"trash" 
+                                                                            objectName:node.pithosObject.name];
+        if (safeObjectName) {
+            ASIPithosObjectRequest *objectRequest = [ASIPithosObjectRequest moveObjectDataRequestWithContainerName:node.pithosContainer.name 
+                                                                                                        objectName:node.pithosObject.name 
+                                                                                                       contentType:nil 
+                                                                                                   contentEncoding:nil 
+                                                                                                contentDisposition:nil 
+                                                                                                          manifest:nil 
+                                                                                                           sharing:nil 
+                                                                                                          isPublic:ASIPithosObjectRequestPublicIgnore 
+                                                                                                          metadata:nil 
+                                                                                          destinationContainerName:@"trash" 
+                                                                                             destinationObjectName:safeObjectName];
+            objectRequest.delegate = self;
+            objectRequest.didFinishSelector = @selector(moveToTrashFinished:);
+            objectRequest.didFailSelector = @selector(moveToTrashFailed:);
+            [objectRequest startAsynchronous];
+        }
+    } else if ([node class] == [PithosSubdirNode class]) {
+        NSString *safeObjectName = [PithosFileUtilities safeSubdirNameForContainerName:@"trash" 
+                                                                            subdirName:node.pithosObject.name];
+        if (safeObjectName) {
+            NSArray *objectRequests = [PithosFileUtilities moveObjectRequestsForSubdirWithContainerName:node.pithosContainer.name 
+                                                                                             objectName:node.pithosObject.name 
+                                                                               destinationContainerName:@"trash" 
+                                                                                  destinationObjectName:safeObjectName];
+            if (objectRequests) {
+                for (ASIPithosObjectRequest *objectRequest in objectRequests) {
+                    objectRequest.delegate = self;
+                    objectRequest.didFinishSelector = @selector(moveToTrashFinished:);
+                    objectRequest.didFailSelector = @selector(moveToTrashFailed:);
+                    [objectRequest startAsynchronous];
+                }
+            }
+        }        
+    }
+}
+
+#pragma mark -
+#pragma mark Menu Actions ASIHTTPRequestDelegate
+
+- (void)deleteObjectFinished:(ASIPithosObjectRequest *)objectRequest {
+    if (objectRequest.responseStatusCode == 204) {
+        NSLog(@"Object deleted: %@", [objectRequest url]);
+        [self refresh:nil];
+    } else {
+        [PithosFileUtilities unexpectedResponseStatusAlertWithRequest:objectRequest];
+    }
+}
+
+- (void)deleteObjectFailed:(ASIPithosObjectRequest *)objectRequest {
+    NSLog(@"Delete of object failed");
+    [PithosFileUtilities httpRequestErrorAlertWithRequest:objectRequest];
+}
+
+- (void)moveToTrashFinished:(ASIPithosObjectRequest *)objectRequest {
+    if (objectRequest.responseStatusCode == 201) {
+        NSLog(@"Object moved: %@", [objectRequest url]);
+        [self refresh:nil];
+    } else {
+        [PithosFileUtilities unexpectedResponseStatusAlertWithRequest:objectRequest];
+    }
+}
+
+- (void)moveToTrashFailed:(ASIPithosObjectRequest *)objectRequest {
+    NSLog(@"Move of object failed");
+    [PithosFileUtilities httpRequestErrorAlertWithRequest:objectRequest];
+}
+
+
 @end
\ No newline at end of file