In folder view controller in iPhone, select file cell to open, or select cell disclos...
[pithos-ios] / Classes / StorageObjectViewController.m
index adc6753..8f68994 100755 (executable)
@@ -29,9 +29,9 @@
 #import <MediaPlayer/MPMoviePlayerController.h>
 #import <MessageUI/MessageUI.h>
 #import "ActivityIndicatorView.h"
-#import "OpenStackAppDelegate.h"
 
 #define kDetails 0
+#define kActions 1
 #define kMetadata 2
 
 #define maxMetadataViewableLength 12
 // TODO: try downloading directly to the file to save memory.  don't use object.data
 
 /*
- Name                           whatever.txt
- Full Path
- Size                           123 KB
- Content Type                   text/plain
- Metadata
- Key                            Value -> tap goes to a metadata item VC to edit or delete
- Key                            Value
- Add Metadata... (if max not already reached)
+Name                            whatever.txt
+Full Path                       folder/whatever.txt
+Size                            123 KB
+Type                            text/plain
+Last Modified                   2012-12-21 11:11:00
+
+Download File (if downloaded, Open File and Mail File as Attachment)
+"After you download the file, you'll be able to attempt to open it and mail is as an attachment."
+
+Metadata
+Key                             Value -> tap goes to a metadata item VC to edit or delete
+Key                             Value
+Add Metadata... (if max not already reached)
+
+Public URL                      On/Off
+
+Share
  
- Download File (if downloaded, Open File and Mail File as Attachment)
- "After you download the file, you'll be able to attempt to open it and mail is as an attachment."
+Versions
  
- Delete Object
- */
+Delete Object
+*/
 
 @implementation StorageObjectViewController
 
-@synthesize account, container, folder, object, tableView, folderViewController;
+@synthesize account, container, folder, object, folderViewController;
 @synthesize oldPubicURI, documentInteractionController, actionSelectedIndexPath, objectIsReadOnly, versionID;
 
-- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
-    return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) || (toInterfaceOrientation == UIInterfaceOrientationPortrait);
-}
-
-- (void)setBackgroundView {
-    UIImageView *logo = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"cloudfiles-large.png"]];
-    
-    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
-        UIView *backgroundContainer = [[UIView alloc] init];
-        backgroundContainer.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
-        backgroundContainer.backgroundColor = [UIColor iPadTableBackgroundColor];
-        logo.contentMode = UIViewContentModeScaleAspectFit;
-        logo.frame = CGRectMake(100.0, 100.0, 1000.0, 1000.0);
-        logo.alpha = 0.5;        
-        [backgroundContainer addSubview:logo];
-        tableView.backgroundView = backgroundContainer;
-        [backgroundContainer release];
-    } else {        
-        self.tableView.backgroundView = nil;
-    }
-    [logo release];    
-}
+#pragma mark - View lifecycle
 
-- (IBAction)homeButtonPressed:(id)sender {
-    [self.navigationController popToRootViewControllerAnimated:YES];
+- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
+    return ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) || (toInterfaceOrientation == UIInterfaceOrientationPortrait);
 }
 
-#pragma mark - View lifecycle
-
 - (void)viewDidLoad {
     [super viewDidLoad];
-        
+    
     objectIsPublicSwitch = [[UISwitch alloc] init];
     [objectIsPublicSwitch addTarget:self action:@selector(objectIsPublicSwitchChanged:) forControlEvents:UIControlEventValueChanged];
     
         self.actionSelectedIndexPath = [request.userInfo objectForKey:@"actionSelectedIndexPath"];
         [request setDownloadProgressDelegate:self];
     }
-    appDelegate = [[UIApplication sharedApplication] delegate];
 }
 
 - (void)viewWillAppear:(BOOL)animated {
     NSIndexPath *selection = [self.tableView indexPathForSelectedRow];
        if (selection)
                [self.tableView deselectRowAtIndexPath:selection animated:YES];
-    if ([appDelegate.cachedObjectsDictionary objectForKey:object.hash] != nil) {
-        if ([[NSFileManager defaultManager] fileExistsAtPath:[appDelegate.cachedObjectsDictionary objectForKey:object.hash]]) {
+    OpenStackAppDelegate *app = [[UIApplication sharedApplication] delegate];
+    if ([app.cachedObjectsDictionary objectForKey:object.hash] != nil) {
+        if ([[NSFileManager defaultManager] fileExistsAtPath:[app.cachedObjectsDictionary objectForKey:object.hash]]) {
             fileDownloaded = YES;
         } else {
             fileDownloaded = NO;
-            [appDelegate.cachedObjectsDictionary removeObjectForKey:object.hash];
-            [appDelegate saveCacheDictionary];
+            [app.cachedObjectsDictionary removeObjectForKey:object.hash];
+            [app saveCacheDictionary];
         }
     } else {
         fileDownloaded = NO;
     }
     
-    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
+    if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) {
         CGRect rect = downloadProgressView.frame;
         rect.size.width = 440.0;
         downloadProgressView.frame = rect;
     }
     
-    //[self setBackgroundView];
-    actionsSection = 1;
     publicLinkSection = 3;
     permissionsSection = 4;
     versionsSection = 5;
     }
 }
 
-#pragma mark - Table view data source
+#pragma mark - Memory management
+
+- (void)dealloc {
+    if (fileDownloading) {
+        OpenStackRequest *request = [self.account.manager.objectDownloadRequests objectForKey:object.fullPath];
+        [request setDownloadProgressDelegate:nil];
+    }
+    [account release];
+    [downloadProgressView release];
+    [cdnURLActionSheet release];
+    [folderViewController release];
+    [objectIsPublicSwitch release];
+    [permissions release];
+    [documentInteractionController release];
+    [actionSelectedIndexPath release];
+    [versionID release];
+    [super dealloc];
+}
+
+#pragma mark - Internal
+
+- (void)objectIsPublicSwitchChanged:(id)sender {
+    NSString *activityMessage = [NSString stringWithFormat:@"Enabling public link.."];
+    self.oldPubicURI = object.publicURI;
+    
+    if (objectIsPublic) {
+        activityMessage = [NSString stringWithFormat:@"Disabling public link.."];
+        object.publicURI = @"";
+    } else {
+        object.publicURI = @"TRUE";
+    }
+    __block ActivityIndicatorView *activityIndicatorView = [ActivityIndicatorView activityIndicatorViewWithText:activityMessage
+                                                                                                   andAddToView:self.view
+                                                                                                   scrollOffset:self.tableView.contentOffset.y];
+    objectIsPublic = !objectIsPublic;
+    [[self.account.manager writeObjectMetadata:container object:object]
+     success:^(OpenStackRequest *request) {
+         NSIndexPath *publicURICellIndexPath = [NSIndexPath indexPathForRow:1 inSection:publicLinkSection];
+         if (objectIsPublic) {
+             [[self.account.manager getObjectInfo:container object:object version:versionID]
+              success:^(OpenStackRequest *request) {
+                  [activityIndicatorView removeFromSuperview];
+                  object.publicURI = [request.responseHeaders objectForKey:@"X-Object-Public"];
+                  NSIndexPath *publicURICellIndexPath = [NSIndexPath indexPathForRow:1 inSection:publicLinkSection];
+                  [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:publicURICellIndexPath]
+                                        withRowAnimation:UITableViewRowAnimationBottom];
+              }
+              failure:^(OpenStackRequest *request) {
+                  [activityIndicatorView removeFromSuperview];
+                  [self alert:@"There was a problem retrieving the public link from the server." request:request];
+              }];
+         } else {
+             [activityIndicatorView removeFromSuperview];
+             [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:publicURICellIndexPath]
+                                   withRowAnimation:UITableViewRowAnimationTop];
+         }
+     }
+     failure:^(OpenStackRequest *request) {
+         [activityIndicatorView removeFromSuperview];
+         objectIsPublic = !objectIsPublic;
+         objectIsPublicSwitch.on = !objectIsPublicSwitch.on;
+         object.publicURI = oldPubicURI;
+         [self alert:@"There was a problem enabling the public link." request:request];
+     }];
+}
+
+#pragma mark - Actions
+
+- (void)reloadMetadataSection {
+    __block ActivityIndicatorView *activityIndicatorView = [ActivityIndicatorView activityIndicatorViewWithText:@"Loading metadata..."
+                                                                                                   andAddToView:self.view];
+    [[self.account.manager getObjectInfo:container object:object version:versionID]
+     success:^(OpenStackRequest *request) {
+         [activityIndicatorView removeFromSuperview];
+         object.metadata = [NSMutableDictionary dictionary];
+         for (NSString *header in request.responseHeaders) {
+             NSString *metadataKey;
+             NSString *metadataValue;
+             if ([header rangeOfString:@"X-Object-Meta-"].location != NSNotFound) {
+                 metadataKey = [NSString decodeFromPercentEscape:[header substringFromIndex:14]];
+                 metadataValue = [NSString decodeFromPercentEscape:[request.responseHeaders objectForKey:header]];
+                 [object.metadata setObject:metadataValue forKey:metadataKey];
+             }
+         }
+         NSIndexSet *metadataSections = [NSIndexSet indexSetWithIndex:kMetadata];
+         [self.tableView reloadSections:metadataSections withRowAnimation:UITableViewRowAnimationFade];
+     }
+     failure:^(OpenStackRequest *request) {
+         [activityIndicatorView removeFromSuperview];
+         [self alert:@"There was a problem retrieving the object's metadata." request:request];
+     }];
+}
+
+#pragma mark - UITableViewDataSource
 
 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
     int numberOfSections = 7;
-    if (deleteSection < 0)
-        numberOfSections--;
-    if (versionsSection < 0)
-        numberOfSections--;
     if (publicLinkSection < 0)
         numberOfSections--;
     if (permissionsSection < 0)
         numberOfSections--;
+    if (versionsSection < 0)
+        numberOfSections--;
+    if (deleteSection < 0)
+        numberOfSections--;
 
     return numberOfSections;
 }
 
 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
     if (section == kDetails) {
-        return 4;
+        return (object.lastModifiedString ? 5: 4);
+    } else if (section == kActions) {
+        return 2;
     } else if (section == kMetadata) {
         if (objectIsReadOnly) {
             return [object.metadata count];
         } else {
             return 1 + [object.metadata count];
         }
-    } else if (section == actionsSection) {
-        return 2;
     } else if (section == publicLinkSection) {
         return objectIsPublic ? 2 : 1;
     } else if (section == permissionsSection) {
     }
 }
 
-- (CGFloat)findLabelHeight:(NSString*)text font:(UIFont *)font {
-    CGSize textLabelSize;    
-    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
-        // 616, 678
-        textLabelSize = CGSizeMake(596.0, 9000.0f);
-    } else {
-        textLabelSize = CGSizeMake(280.0, 9000.0f);
-    }
-    CGSize stringSize = [text sizeWithFont:font constrainedToSize:textLabelSize lineBreakMode:UILineBreakModeCharacterWrap];
-    return stringSize.height;
-}
-
 - (CGFloat)tableView:(UITableView *)aTableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
     CGFloat result = aTableView.rowHeight;
-
-    if (indexPath.section == kDetails && indexPath.row == 1) {
-        CGSize textLabelSize;
-        if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
-            textLabelSize = CGSizeMake(537.0, 9000.0f);
-        } else {
-            textLabelSize = CGSizeMake(221.0, 9000.0f);
-        }
-        CGSize stringSize = [object.fullPath sizeWithFont:[UIFont systemFontOfSize:18.0] constrainedToSize:textLabelSize lineBreakMode:UILineBreakModeWordWrap];
-        return 22.0 + stringSize.height;
-    } else if (indexPath.section == kDetails && indexPath.row == 0) {
-        CGSize textLabelSize;
-        if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
-            textLabelSize = CGSizeMake(537.0, 9000.0f);
-        } else {
-            textLabelSize = CGSizeMake(221.0, 9000.0f);
+    if ((indexPath.section == kDetails) && ((indexPath.row == 0) || (indexPath.row == 1))) {
+        NSString *text;
+        if (indexPath.row == 0) {
+            text = object.name;
+        } else if (indexPath.row == 1) {
+            text = object.fullPath;
         }
-        CGSize stringSize = [object.name sizeWithFont:[UIFont systemFontOfSize:18.0] constrainedToSize:textLabelSize lineBreakMode:UILineBreakModeWordWrap];
-        return 22.0 + stringSize.height;
-    } else if (indexPath.section == publicLinkSection && indexPath.row == 1) {
-        NSString *publicLinkUrl = [NSString stringWithFormat:@"%@%@",
-                                   account.pithosPublicLinkURLPrefix,
-                                   self.object.publicURI];
-                                   
-        result = 30.0 + [self findLabelHeight:publicLinkUrl font:[UIFont systemFontOfSize:15.0]];
+        result = 22.0 + [text sizeWithFont:[UIFont systemFontOfSize:18.0]
+                         constrainedToSize:(([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) ?
+                                            CGSizeMake(537.0, 9000.0) :
+                                            CGSizeMake(221.0, 9000.0))
+                             lineBreakMode:UILineBreakModeCharacterWrap].height;
+    } else if ((indexPath.section == publicLinkSection) && (indexPath.row == 1)) {
+        NSURL *publicLinkURL = [account.pithosPublicLinkURLPrefix URLByAppendingPathComponent:
+                                [NSString encodeToPercentEscape:[self.object.publicURI substringFromIndex:1]
+                                             charactersToEncode:@"!*'();:@&=+$,?%#[]"]];
+        result = 30.0 + [[publicLinkURL description] sizeWithFont:[UIFont systemFontOfSize:18.0]
+                                                constrainedToSize:(([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) ?
+                                                                   CGSizeMake(596.0, 9000.0) :
+                                                                   CGSizeMake(280.0, 9000.0))
+                                                    lineBreakMode:UILineBreakModeCharacterWrap].height;
     }
     return MAX(aTableView.rowHeight, result);
 }
         cell.textView.backgroundColor = [UIColor clearColor];
         cell.textView.font = [UIFont systemFontOfSize:15.0];
         cell.textView.dataDetectorTypes = UIDataDetectorTypeLink;
-        cell.textView.text = [NSString stringWithFormat:@"%@%@",
-                              account.pithosPublicLinkURLPrefix,
-                              [NSString encodeToPercentEscape:self.object.publicURI charactersToEncode:@"!*'();:@&=+$,?%#[]"]];
+        cell.textView.text = [[account.pithosPublicLinkURLPrefix URLByAppendingPathComponent:
+                               [NSString encodeToPercentEscape:[self.object.publicURI substringFromIndex:1]
+                                            charactersToEncode:@"!*'();:@&=+$,?%#[]"]] description];
         cell.selectionStyle = UITableViewCellSelectionStyleNone;
         cell.accessoryView = UITableViewCellAccessoryNone;
         return cell;
     
     if (indexPath.section == deleteSection) {
         static NSString *CellIdentifier = @"DeleteCell";
-        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
+        UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
         if (cell == nil) {
             cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
             cell.selectionStyle = UITableViewCellSelectionStyleBlue;
     }
     cell.textLabel.textColor = [UIColor blackColor];
     cell.detailTextLabel.numberOfLines = 0;
-    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
+    if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) {
         cell.backgroundColor = [UIColor colorWithRed:1 green:1 blue:1 alpha:0.8];
     }
     cell.userInteractionEnabled = YES;
         } else if (indexPath.row == 3) {
             cell.textLabel.text = @"Type";
             cell.detailTextLabel.text = object.contentType;
+        } else if (indexPath.row == 4) {
+            cell.textLabel.text = @"Last Modified";
+            cell.detailTextLabel.text = object.lastModifiedString;
         }
     } else if (indexPath.section == kMetadata) {
         if (objectIsReadOnly) {
             cell.detailTextLabel.lineBreakMode = UILineBreakModeTailTruncation;
             cell.detailTextLabel.text = accessType;
         }
-    } else if (indexPath.section == actionsSection) {
+    } else if (indexPath.section == kActions) {
         if (fileDownloading) {
             if (actionSelectedIndexPath.row == indexPath.row) {
                 cell.accessoryView = downloadProgressView;
     return cell;
 }
 
-#pragma mark -
-#pragma mark Table view delegate
-
-- (void)reloadActionsTitleRow:(NSTimer *)timer {
-    [[timer.userInfo objectForKey:@"tableView"] reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:0 inSection:actionsSection]] withRowAnimation:UITableViewRowAnimationNone];
-}
+#pragma mark - UITableViewDelegate
 
 - (void)tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
     if (indexPath.section == kMetadata) {
         vc.folderViewController = folderViewController;
         [self.navigationController pushViewController:vc animated:YES];
         [vc release];
-    } else if (indexPath.section == actionsSection) {
+    } else if (indexPath.section == kActions) {
         if (!fileDownloaded) {
             if (!fileDownloading) {
                 // download the file
                  failure:^(OpenStackRequest *request) {
                      fileDownloaded = NO;
                      fileDownloading = NO;
-                     [self alert:@"File failed to download" request:request];
+                     [self alert:@"File failed to download." request:request];
                      [self.tableView reloadData];
                  }];
-                [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:indexPath.row inSection:actionsSection]] withRowAnimation:UITableViewRowAnimationNone];
+                [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:indexPath.row inSection:kActions]] withRowAnimation:UITableViewRowAnimationNone];
             }
         } else if (indexPath.row == 0) {        
             if (fileDownloaded) {
-                NSString *filePath = [appDelegate.cachedObjectsDictionary objectForKey:object.hash];                                 
+                OpenStackAppDelegate *app = [[UIApplication sharedApplication] delegate];
+                NSString *filePath = [app.cachedObjectsDictionary objectForKey:object.hash];
                 self.documentInteractionController = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:filePath]];
                 self.documentInteractionController.delegate = self;
                 self.documentInteractionController.name = object.name;
                     }
                 } 
                 
-                [self.tableView deselectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:actionsSection] animated:YES];                
+                [self.tableView deselectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:kActions] animated:YES];
                 
             } 
         } else if (indexPath.row == 1) {
                 [vc setSubject:self.object.name];
                 [vc addAttachmentData:data mimeType:self.object.contentType fileName:self.object.name];
                 [vc setMessageBody:@"" isHTML:NO];    
-                if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
+                if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) {
                     vc.modalPresentationStyle = UIModalPresentationPageSheet;
                 }                
                 [self presentModalViewController:vc animated:YES];
     }
 }
 
-
-#pragma mark -
-#pragma mark Document Interaction Controller Delegate
+#pragma mark - UIDocumentInteractionControllerDelegate
 
 - (UIViewController *)documentInteractionControllerViewControllerForPreview:(UIDocumentInteractionController *) controller {
     return self.navigationController;
 }
 
-- (void)documentInteractionControllerDidEndPreview:(UIDocumentInteractionController *)controllers {
-    [self.tableView deselectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:actionsSection] animated:YES];
-}
-
-#pragma mark -
-#pragma mark Action Sheet Delegate
+#pragma mark - UIActionSheetDelegate
 
 - (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
     if (buttonIndex == 0) {
         [[self.account.manager deleteObject:self.container object:self.object] 
          success:^(OpenStackRequest *request) {
              [activityIndicatorView removeFromSuperview];
-             if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
+             if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone) {
                  [self.navigationController popViewControllerAnimated:YES];
                  if (account.shared)
                      self.folderViewController.needsRefreshing = YES;
-             } else if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
+             } else if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) {
                  self.folderViewController.selectedObjectViewController = nil;
                  if (!account.shared)
                      [self.folderViewController setDetailViewController];
     [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
 }
 
-#pragma mark - Mail Composer Delegate
+#pragma mark - MFMailComposeViewControllerDelegate
 
 // Dismisses the email composition interface when users tap Cancel or Send.
 - (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error { 
        [self dismissModalViewControllerAnimated:YES];
-    [self.tableView deselectRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:actionsSection] animated:YES];
-}
-
-#pragma mark - Switches
-
-- (void)objectIsPublicSwitchChanged:(id)sender {
-    NSString *activityMessage = [NSString stringWithFormat:@"Enabling public link.."];
-    self.oldPubicURI = object.publicURI;
-    
-    if (objectIsPublic) {
-        activityMessage = [NSString stringWithFormat:@"Disabling public link.."];
-        object.publicURI = @"";
-    } else {
-        object.publicURI = @"TRUE";
-    }
-    __block ActivityIndicatorView *activityIndicatorView = [ActivityIndicatorView activityIndicatorViewWithText:activityMessage
-                                                                                                   andAddToView:self.view
-                                                                                                   scrollOffset:self.tableView.contentOffset.y];
-    objectIsPublic = !objectIsPublic;
-    [[self.account.manager writeObjectMetadata:container object:object]
-     success:^(OpenStackRequest *request) {
-         NSIndexPath *publicURICellIndexPath = [NSIndexPath indexPathForRow:1 inSection:publicLinkSection];
-         if (objectIsPublic) {
-             [[self.account.manager getObjectInfo:container object:object version:versionID] 
-              success:^(OpenStackRequest *request) {
-                  [activityIndicatorView removeFromSuperview];
-                  object.publicURI = [request.responseHeaders objectForKey:@"X-Object-Public"];
-                  NSIndexPath *publicURICellIndexPath = [NSIndexPath indexPathForRow:1 inSection:publicLinkSection];
-                  [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:publicURICellIndexPath]
-                                        withRowAnimation:UITableViewRowAnimationBottom];
-              }
-              failure:^(OpenStackRequest *request) {
-                  [activityIndicatorView removeFromSuperview];
-                  [self alert:@"There was a problem retrieving the public link from the server." request:request]; 
-              }];
-         } else {
-             [activityIndicatorView removeFromSuperview];
-             [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:publicURICellIndexPath]
-                                   withRowAnimation:UITableViewRowAnimationTop];
-         }
-     }
-     failure:^(OpenStackRequest *request) {
-         [activityIndicatorView removeFromSuperview];
-         objectIsPublic = !objectIsPublic;
-         objectIsPublicSwitch.on = !objectIsPublicSwitch.on;
-         object.publicURI = oldPubicURI;
-         [self alert:@"There was a problem enabling the public link." request:request];           
-     }];
-}
-
-#pragma mark - Memory management
-
-- (void)dealloc {
-    if (fileDownloading) {
-        OpenStackRequest *request = [self.account.manager.objectDownloadRequests objectForKey:object.fullPath];
-        [request setDownloadProgressDelegate:nil];
-    }
-    [account release];
-    [downloadProgressView release];
-    [cdnURLActionSheet release];
-    [tableView release];
-    [folderViewController release];
-    [objectIsPublicSwitch release];
-    [permissions release];
-    [documentInteractionController release];
-    [actionSelectedIndexPath release];
-    [versionID release];
-    [super dealloc];
-}
-
-#pragma mark - Helper functions
-
-- (void)reloadMetadataSection {
-    __block ActivityIndicatorView *activityIndicatorView = [ActivityIndicatorView activityIndicatorViewWithText:@"Loading metadata..."
-                                                                                                   andAddToView:self.view];
-    [[self.account.manager getObjectInfo:container object:object version:versionID]
-     success:^(OpenStackRequest *request) {
-         [activityIndicatorView removeFromSuperview];         
-         object.metadata = [NSMutableDictionary dictionary];
-         for (NSString *header in request.responseHeaders) {
-             NSString *metadataKey;
-             NSString *metadataValue;
-             if ([header rangeOfString:@"X-Object-Meta-"].location != NSNotFound) {
-                 metadataKey = [NSString decodeFromPercentEscape:[header substringFromIndex:14]];
-                 metadataValue = [NSString decodeFromPercentEscape:[request.responseHeaders objectForKey:header]];
-                 [object.metadata setObject:metadataValue forKey:metadataKey];
-             }
-         }   
-         NSIndexSet *metadataSections = [NSIndexSet indexSetWithIndex:kMetadata];
-         [self.tableView reloadSections:metadataSections withRowAnimation:UITableViewRowAnimationFade];
-     }
-     failure:^(OpenStackRequest *request) {
-         [activityIndicatorView removeFromSuperview];
-         [self alert:@"There was a problem retrieving the object's metadata." request:request]; 
-     }];
+    [self.tableView deselectRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:kActions] animated:YES];
 }
 
 @end