0be1fa29f291be08e48268c5d3131e852f3288de
[pithos-ios] / Classes / FolderViewController.m
1 //
2 //  FolderViewController.m
3 //  OpenStack
4 //
5 //  Created by Mike Mayo on 12/15/10.
6 //  The OpenStack project is provided under the Apache 2.0 license.
7 //
8
9 #import "FolderViewController.h"
10 #import "OpenStackAccount.h"
11 #import "Container.h"
12 #import "Folder.h"
13 #import "StorageObject.h"
14 #import "StorageObjectViewController.h"
15 #import "ContainerDetailViewController.h"
16 #import "AccountManager.h"
17 #import "ActivityIndicatorView.h"
18 #import "ContainersViewController.h"
19 #import "UIViewController+Conveniences.h"
20 #import "AddObjectViewController.h"
21 #import "OpenStackAppDelegate.h"
22 #import "RootViewController.h"
23 #import "FolderDetailViewController.h"
24 #import "AccountHomeViewController.h"
25 #import "PithosImageViewController.h"
26 #import "OpenStackRequest.h"
27 #import "JSON.h"
28 #import "APICallback.h"
29 #import "OpenStackAppDelegate.h"
30 #import <MobileCoreServices/MobileCoreServices.h>
31 #import "ComputeModel.h"
32
33 @implementation FolderViewController
34
35 @synthesize account, container, folder, name, containersViewController, selectedContainerIndexPath, contentsLoaded, parentFolderViewController, selectedFolderIndexPath, tableView, needsRefreshing, folderHasBeenRemoved, refreshWhenAppeared, folderDetailVC, selectedObjectViewController, refreshButton;
36 @synthesize searchBar, searchDisplayController, searchFilter;
37
38 #pragma mark - View lifecycle
39
40 - (void)viewDidLoad {
41     [super viewDidLoad];
42     [self addAddButton];
43     [self addHomeButton];
44     
45     searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:self.searchBar contentsController:self];
46     searchDisplayController.delegate = self;
47     searchDisplayController.searchResultsDataSource = self;
48     searchDisplayController.searchResultsDelegate = self;
49 }
50
51 - (void)viewWillAppear:(BOOL)animated {
52     [super viewWillAppear:animated];
53     if (self.name && self.name.length) {
54         self.navigationItem.title = self.name;
55     } else {
56         self.navigationItem.title = self.container.name;
57     }
58 }
59
60 - (void)viewDidAppear:(BOOL)animated {
61     [super viewDidAppear:animated];
62     if (!self.folder) {
63         if (folderHasBeenRemoved) {
64             if (needsRefreshing) 
65                 self.parentFolderViewController.needsRefreshing = YES;
66             [self.navigationController popViewControllerAnimated:YES];
67         } else {
68             [self refreshButtonPressed:nil];
69         }
70     } else if (self.needsRefreshing) {
71         self.parentFolderViewController.needsRefreshing = YES;
72         if (refreshWhenAppeared) {
73             [self refreshButtonPressed:nil];
74             refreshWhenAppeared = NO;
75         }
76         if (account.shared && !folder.objectsAndFoldersCount) {
77             [self.navigationController popViewControllerAnimated:YES];
78         }
79     }
80 }
81
82 - (void)viewWillDisappear:(BOOL)animated {
83     [super viewWillDisappear:animated];
84     if (![self.navigationController.viewControllers containsObject:self] &&
85         self.parentViewController &&
86         (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)) {
87         [parentFolderViewController setDetailViewController];
88     }
89 }
90
91 #pragma mark - Memory management
92
93 - (void)dealloc {
94     [account release];
95     [container release];
96     [folder release];
97     [containersViewController release];
98     [selectedContainerIndexPath release];
99     [parentFolderViewController release];
100     [selectedFolderIndexPath release];
101     [refreshButton release];
102     [searchBar release];
103     [searchDisplayController release];
104     [searchFilter release];
105     [super dealloc];
106 }
107
108 #pragma mark - Internal
109
110 - (void)showSearchBar:(BOOL)show {
111     if (show && ![self.tableView.tableHeaderView isEqual:self.searchBar]) {
112         self.searchBar.hidden = NO;
113         self.tableView.tableHeaderView = self.searchBar;
114         if (UI_USER_INTERFACE_IDIOM() != UIUserInterfaceIdiomPad) {
115             self.tableView.contentOffset = CGPointMake(0.0, 44.0);
116         }
117     } else if (!show) {
118         self.tableView.tableHeaderView = nil;
119         self.searchBar.hidden = YES;
120     }
121 }
122
123 - (void)reloadFolderViewControllers {
124     NSArray *viewControllers = [self.navigationController viewControllers];
125     
126     int rootFolderControllerIndex = [viewControllers indexOfObject:self.containersViewController] + 1;
127     FolderViewController *rootFolderViewController = [viewControllers objectAtIndex:rootFolderControllerIndex];
128     rootFolderViewController.folder = self.container.rootFolder;
129     
130     for (int i = rootFolderControllerIndex + 1; i < [viewControllers count]; i++) {
131         FolderViewController *folderViewController = [viewControllers objectAtIndex:i];
132         Folder *parentFolder = folderViewController.parentFolderViewController.folder;
133         
134         folderViewController.folder = [parentFolder.folders objectForKey:folderViewController.folder.name];
135         if (!folderViewController.folder)
136             folderViewController.folderHasBeenRemoved = YES;
137     }
138     if (!self.folder || (account.shared && !folder.objectsAndFoldersCount)) {
139         if (needsRefreshing && self.parentFolderViewController) {
140             self.parentFolderViewController.needsRefreshing = YES;
141         }
142         [self.navigationController popViewControllerAnimated:YES];
143     } else if ((UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) && account.shared) {
144         [self setDetailViewController];
145     }
146 }
147
148 - (void)deleteFolderRow {
149     [self.parentFolderViewController.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:selectedFolderIndexPath]
150                                                      withRowAnimation:UITableViewRowAnimationLeft];
151     if (self.parentFolderViewController.searchDisplayController.active &&
152         self.parentFolderViewController.searchFilter && self.parentFolderViewController.searchFilter.length)
153         [self.parentFolderViewController.searchDisplayController.searchResultsTableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:selectedFolderIndexPath]
154                                                                                               withRowAnimation:UITableViewRowAnimationLeft];
155 }
156
157 - (void)deleteObjectRow:(NSTimer *)timer {
158     [self.folder removeObject:[timer.userInfo objectForKey:@"object"]];
159     [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:[timer.userInfo objectForKey:@"indexPath"]]
160                           withRowAnimation:UITableViewRowAnimationLeft];
161     if (self.searchDisplayController.active && self.searchFilter && self.searchFilter.length)
162         [self.searchDisplayController.searchResultsTableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:[timer.userInfo objectForKey:@"indexPath"]]
163                                                                    withRowAnimation:UITableViewRowAnimationLeft];
164     self.refreshButton.enabled = YES;
165 }
166
167 - (NSArray *)searchResults {
168     return [self.folder sortedContentsUsingFilter:self.searchFilter
169                                          andScope:[self.searchBar.scopeButtonTitles objectAtIndex:self.searchBar.selectedScopeButtonIndex]];
170 }
171
172 #pragma mark - Properties
173
174 - (UISearchBar *)searchBar {
175     if (!searchBar) {
176         searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 44.0)];
177         searchBar.placeholder = @"Search Folder";
178         searchBar.barStyle = UIBarStyleBlackOpaque;
179         searchBar.autocapitalizationType = UITextAutocapitalizationTypeNone;
180         searchBar.autocorrectionType = UITextAutocorrectionTypeNo;
181         searchBar.scopeButtonTitles = @[@"name", @"date", @"type", @"all"];
182         searchBar.selectedScopeButtonIndex = 0;
183         searchBar.hidden = YES;
184     }
185     return searchBar;
186 }
187
188 - (void)setFolder:(Folder *)aFolder {
189     [folder release];
190     folder = [aFolder retain];
191     [self showSearchBar:(self.contentsLoaded && self.folder && self.folder.objectsAndFoldersCount)];
192     if ((UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) && self.selectedObjectViewController && folder) {
193         StorageObject *newObject = [folder.objects objectForKey:self.selectedObjectViewController.object.name];
194         if (newObject)
195             self.selectedObjectViewController.object = newObject;
196         // We don't set nil otherwise, this will be done in reloadData, when setDetailViewController is called.
197     }
198     [self reloadData];
199 }
200
201 #pragma mark - Actions
202
203 - (void)reloadData {
204     [self.tableView reloadData];
205     BOOL searchResultsShown = self.searchDisplayController.active && self.searchFilter && self.searchFilter.length;
206     if (searchResultsShown)
207         [self.searchDisplayController.searchResultsTableView reloadData];
208     if ((UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) && self.selectedObjectViewController) {
209         NSUInteger selectedIndex = [[self searchResults] indexOfObject:self.selectedObjectViewController.object];
210         if (selectedIndex == NSNotFound) {
211             [self setDetailViewController];
212         } else {
213             NSIndexPath *selectIndexPath = [NSIndexPath indexPathForRow:selectedIndex inSection:0];
214             [self.tableView selectRowAtIndexPath:selectIndexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
215             if (searchResultsShown)
216                 [self.searchDisplayController.searchResultsTableView selectRowAtIndexPath:selectIndexPath
217                                                                                  animated:NO
218                                                                            scrollPosition:UITableViewScrollPositionNone];
219         }
220     }
221 }
222
223 - (void)setDetailViewController {
224     self.selectedObjectViewController = nil;
225     if ([self.folder isEqual:self.container.rootFolder]) {
226         ContainerDetailViewController *vc = [[ContainerDetailViewController alloc] initWithNibName:@"ContainerDetailViewController" bundle:nil];
227         vc.account = self.account;
228         vc.container = self.container;
229         vc.containersViewController = self.containersViewController;
230         vc.rootFolderViewController = self;
231         vc.selectedContainerIndexPath = self.selectedContainerIndexPath;
232         [self presentPrimaryViewController:vc];
233         self.containersViewController.containerDetailViewController = vc;
234         [vc release];
235     } else {
236         FolderDetailViewController *vc = [[FolderDetailViewController alloc] initWithNibName:@"FolderDetailViewController" bundle:nil];
237         vc.account = self.account;
238         vc.container = self.container;
239         vc.folder = self.folder;
240         vc.folderViewController = self.parentFolderViewController;
241         [self presentPrimaryViewController:vc];
242         self.parentFolderViewController.folderDetailVC = vc;
243         [vc release];
244     }
245 }
246
247 - (void)deleteAnimatedObject:(StorageObject *)object {
248     NSIndexPath *deleteIndexPath = [NSIndexPath indexPathForRow:[[self searchResults] indexOfObject:object] inSection:0];
249     [self.tableView selectRowAtIndexPath:deleteIndexPath animated:YES scrollPosition:UITableViewScrollPositionNone];
250     if (self.searchDisplayController.active && self.searchFilter && self.searchFilter.length)
251         [self.searchDisplayController.searchResultsTableView selectRowAtIndexPath:deleteIndexPath
252                                                                          animated:YES
253                                                                    scrollPosition:UITableViewScrollPositionNone];
254     NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:object, @"object", deleteIndexPath, @"indexPath", nil];
255     [NSTimer scheduledTimerWithTimeInterval:0.75 target:self selector:@selector(deleteObjectRow:) userInfo:userInfo repeats:NO];
256 }
257
258 #pragma mark - UIScrollViewDelegate
259
260 - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
261     if ((UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) && (scrollView == self.tableView) &&
262         !self.searchBar.hidden && !self.searchDisplayController.active) {
263         CGRect searchBarFrame = self.searchBar.frame;
264         searchBarFrame.origin.y = scrollView.contentOffset.y;
265         searchBar.frame = searchBarFrame;
266     }
267 }
268
269 #pragma mark - UITableViewDataSource
270
271 - (NSInteger)tableView:(UITableView *)aTableView numberOfRowsInSection:(NSInteger)section {
272     if (self.folder.objectsAndFoldersCount) {
273         // For the search results tableView this will be returned because search is allowed only when the folder is not empty.
274         return [[self searchResults] count];
275     } else if (contentsLoaded) {
276         return 1;
277     } else {
278         return 0;
279     }
280 }
281
282 - (CGFloat)tableView:(UITableView *)aTableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
283     if (self.folder.objectsAndFoldersCount) {
284         // For the search results tableView this will be returned because search is allowed only when the folder is not empty.
285         aTableView.scrollEnabled = YES;
286         aTableView.allowsSelection = YES;
287         return aTableView.rowHeight;
288     } else {
289         aTableView.scrollEnabled = NO;
290         aTableView.allowsSelection = NO;
291         return aTableView.frame.size.height;
292     }
293 }
294
295 - (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
296     if (!self.folder.objectsAndFoldersCount) {
297         NSString *noFoldersTitle = (self.account.shared || self.account.sharingAccount) ?
298             @"No shared Files or Folders" : @"No Files or Folders";
299         NSString *noFoldersSubtitle = (self.account.shared || self.account.sharingAccount || [self.folder.name hasSuffix:@"/"]) ?
300             @"" : @"Tap the + button to create a new one";
301         NSString *deleteFolderButtonTitle = (self.account.shared || self.account.sharingAccount) ? nil : @"Delete Folder";
302         SEL deleteButtonSelector = (self.account.shared || self.account.sharingAccount) ? nil : @selector(deleteButtonPressed:);
303         self.navigationItem.rightBarButtonItem.enabled = (self.account.shared || [self.folder.name hasSuffix:@"/"]) ? NO : YES;
304         
305         if ([self.container.rootFolder isEqual:self.folder]) {
306             return [self tableView:aTableView
307                 emptyCellWithImage:[UIImage imageNamed:@"empty-files.png"]
308                              title:noFoldersTitle
309                           subtitle:noFoldersSubtitle];
310         } else {
311             return [self tableView:aTableView
312                 emptyCellWithImage:[UIImage imageNamed:@"empty-files.png"]
313                              title:noFoldersTitle
314                           subtitle:noFoldersSubtitle
315                  deleteButtonTitle:deleteFolderButtonTitle
316               deleteButtonSelector:deleteButtonSelector];
317         }
318     } else {
319         // For the search results tableView this will be returned because search is allowed only when the folder is not empty.
320         static NSString *CellIdentifier = @"Cell";
321         UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:CellIdentifier];
322         if (!cell)
323             cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
324         
325         id item = [[self searchResults] objectAtIndex:indexPath.row];
326         if ([[item class] isEqual:[Folder class]]) {
327             Folder *cellFolder = (Folder *)item;
328             cell.textLabel.text = cellFolder.name;
329             [cell.textLabel setLineBreakMode:UILineBreakModeTailTruncation];
330             if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
331                 cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
332             } else {
333                 cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
334             }
335             
336             cell.imageView.image = [UIImage imageNamed:@"folder-icon.png"];
337             
338             NSString *folderString = @"";
339             if (cellFolder.folders.count > 1) {
340                 folderString = [NSString stringWithFormat:@"%u folders, ", cellFolder.folders.count];
341             } else if (cellFolder.folders.count > 0) {
342                 folderString = @"1 folder, ";
343             }
344             NSString *objectString = @"";
345             if (cellFolder.objects.count != 1) {
346                 objectString = [NSString stringWithFormat:@"%u objects", cellFolder.objects.count];
347             } else {
348                 objectString = @"1 object";
349             }
350             cell.detailTextLabel.text = [NSString stringWithFormat:@"%@%@", folderString, objectString];
351         } else if ([[item class] isEqual:[StorageObject class]]) {
352             StorageObject *cellObject = (StorageObject *)item;
353             cell.textLabel.text = cellObject.name;
354             [cell.textLabel setLineBreakMode:UILineBreakModeMiddleTruncation];
355             if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
356                 cell.accessoryType = UITableViewCellAccessoryNone;
357             } else {
358                 cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
359             }
360             
361             CFStringRef mimeType = (CFStringRef)cellObject.contentType;
362             CFStringRef uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, mimeType, NULL);
363             NSString *emptyPath = [[NSBundle mainBundle] pathForResource:@"empty-file" ofType:@""];
364             UIDocumentInteractionController *udic = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:emptyPath]];
365             if (((NSString *)uti).length > 0)
366                 udic.UTI = (NSString *)uti;
367             if (udic.icons.count > 0)
368                 cell.imageView.image = [udic.icons objectAtIndex:0];
369             
370             if (cellObject.lastModifiedString) {
371                 cell.detailTextLabel.text = [NSString stringWithFormat:@"%@, %@", cellObject.humanizedBytes, cellObject.lastModifiedString];
372             } else {
373                 cell.detailTextLabel.text = cellObject.humanizedBytes;
374             }
375         }
376         
377         return cell;
378     }        
379 }
380
381 #pragma mark - UITableViewDelegate
382
383 - (void)tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
384     if (folder.objectsAndFoldersCount) {
385         id item = [[self searchResults] objectAtIndex:indexPath.row];
386         if ([[item class] isEqual:[Folder class]]) {
387             FolderViewController *vc = [[FolderViewController alloc] initWithNibName:@"FolderViewController" bundle:nil];
388             vc.account = self.account;
389             vc.container = self.container;
390             vc.name = [item name];
391             vc.selectedFolderIndexPath = indexPath;
392             vc.parentFolderViewController = self;
393             vc.containersViewController = self.containersViewController;
394             [self.navigationController pushViewController:vc animated:YES];
395             vc.contentsLoaded = YES;
396             vc.folder = item;
397             [aTableView deselectRowAtIndexPath:indexPath animated:YES];
398             if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
399                 self.selectedObjectViewController = nil;
400                 FolderDetailViewController *folderDetailViewController = [[FolderDetailViewController alloc] initWithNibName:@"FolderDetailViewController" bundle:nil];
401                 folderDetailViewController.account = account;
402                 folderDetailViewController.container = container;
403                 folderDetailViewController.folder = item;
404                 folderDetailViewController.folderViewController = vc;
405                 [self presentPrimaryViewController:folderDetailViewController];
406                 self.folderDetailVC = folderDetailViewController;
407                 [folderDetailViewController release];
408             }
409             [vc release];
410         } else if ([[item class] isEqual:[StorageObject class]]) {
411             StorageObjectViewController *vc = [[StorageObjectViewController alloc] initWithNibName:@"StorageObjectViewController" bundle:nil];
412             vc.account = self.account;
413             vc.container = self.container;
414             vc.folder = self.folder;
415             vc.object = item;
416             vc.folderViewController = self;
417             [self presentPrimaryViewController:vc];
418             if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
419                 self.selectedObjectViewController = vc;
420                 OpenStackAppDelegate *app = [[UIApplication sharedApplication] delegate];
421                 if (app.rootViewController.popoverController) {
422                     [app.rootViewController.popoverController dismissPopoverAnimated:YES];
423                 }
424             } else {
425                 [aTableView deselectRowAtIndexPath:indexPath animated:YES];
426             }
427             [vc release];
428         }
429     }
430 }
431
432 - (void)tableView:(UITableView *)aTableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath {
433     FolderDetailViewController *vc = [[FolderDetailViewController alloc] initWithNibName:@"FolderDetailViewController" bundle:nil];
434     vc.account = account;
435     vc.container = container;
436     vc.folder = [[self searchResults] objectAtIndex:indexPath.row];
437     vc.folderViewController = self;
438     [self.navigationController pushViewController:vc animated:YES];
439     [vc release];
440 }
441
442 #pragma mark - UISearchDisplayDelegate
443
444 - (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
445     self.searchFilter = searchString;
446     [self reloadData];
447     return NO;
448 }
449
450 - (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption {
451     [self reloadData];
452     return NO;
453 }
454
455 - (void)searchDisplayControllerWillEndSearch:(UISearchDisplayController *)controller {
456     self.searchFilter = nil;
457     [self reloadData];
458 }
459
460 #pragma mark - Button Handlers
461
462 - (IBAction)homeButtonPressed:(id)sender {
463     [self.navigationController popToViewController:containersViewController.accountHomeViewController animated:YES];
464 }
465
466 - (IBAction)refreshButtonPressed:(id)sender {
467     activityIndicatorView = [[ActivityIndicatorView alloc] initWithFrame:[ActivityIndicatorView frameForText:@"Loading..."] text:@"Loading..."];
468     [activityIndicatorView addToView:self.view];
469     
470     [self.account.manager getObjects:self.container];
471     successObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"getObjectsSucceeded"
472                                                                         object:self.container
473                                                                          queue:[NSOperationQueue mainQueue]
474                                                                     usingBlock:^(NSNotification* notification)
475     {
476         [activityIndicatorView removeFromSuperviewAndRelease];
477         contentsLoaded = YES;
478         [self reloadFolderViewControllers];
479         needsRefreshing = NO;
480         if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
481            if (self.selectedObjectViewController) {
482                [self.selectedObjectViewController reloadMetadataSection];
483            } else if ([self.folder isEqual:container.rootFolder]) {
484                [containersViewController.containerDetailViewController reloadMetadataSection];
485            } else if ([parentFolderViewController.folderDetailVC.navigationController.topViewController 
486                        isEqual:parentFolderViewController.folderDetailVC]) {
487                [parentFolderViewController.folderDetailVC reloadMetadataSection];
488            }
489         }
490         [[NSNotificationCenter defaultCenter] removeObserver:successObserver];
491     }];
492     failureObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"getObjectsFailed"
493                                                                         object:self.container
494                                                                          queue:[NSOperationQueue mainQueue]
495                                                                     usingBlock:^(NSNotification* notification)
496     {
497         needsRefreshing = NO;
498         [self reloadData];
499         [activityIndicatorView removeFromSuperviewAndRelease];
500         [self alert:@"Error" message:@"Failed to retrieve files from server"];
501         [[NSNotificationCenter defaultCenter] removeObserver:failureObserver];
502     }];
503 }
504
505 - (void)addButtonPressed:(id)sender {
506     AddObjectViewController *vc = [[AddObjectViewController alloc] initWithNibName:@"AddObjectViewController" bundle:nil];
507     vc.account = self.account;
508     vc.container = self.container;
509     vc.folder = self.folder;
510     vc.folderViewController = self;
511     if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
512         vc.modalPresentationStyle = UIModalPresentationFormSheet;
513         OpenStackAppDelegate *app = [[UIApplication sharedApplication] delegate];
514         if (app.rootViewController.popoverController != nil) {
515             [app.rootViewController.popoverController dismissPopoverAnimated:YES];
516         }
517     }
518     [self presentModalViewControllerWithNavigation:vc animated:YES];
519     [vc release];
520 }
521
522 - (void)deleteButtonPressed:(id)sender {
523     UIActionSheet *deleteActionSheet = [[[UIActionSheet alloc] initWithTitle:@"Are you sure you want to delete this folder? This operation cannot be undone."
524                                                                     delegate:self
525                                                            cancelButtonTitle:@"Cancel"
526                                                       destructiveButtonTitle:@"Delete Folder"
527                                                            otherButtonTitles:nil] autorelease];
528     if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
529         OpenStackAppDelegate *appDelegate = (OpenStackAppDelegate *)[[UIApplication sharedApplication] delegate];
530         [deleteActionSheet showInView:appDelegate.masterNavigationController.view];
531     } else {
532         [deleteActionSheet showInView:self.view];
533     }
534 }
535
536 #pragma mark - UIActionSheetDelegate
537
538 - (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
539     if (buttonIndex == 0) {
540         StorageObject *object = [[StorageObject alloc] init];
541         object.name = object.fullPath = [self.folder fullPath];
542         
543         NSString *activityMessage = @"Deleting folder...";
544         activityIndicatorView = [[ActivityIndicatorView alloc] initWithFrame:[ActivityIndicatorView frameForText:activityMessage] text:activityMessage];
545         [activityIndicatorView addToView:self.view scrollOffset:self.tableView.contentOffset.y];
546
547         [[self.account.manager deleteObject:self.container object:object]
548          success:^(OpenStackRequest *request) {
549              if (self.folder.parent) {
550                  [self.folder.parent removeFolder:self.folder];
551              } else {
552                  [self.container.rootFolder removeFolder:self.folder];
553              }
554              [self.account persist];
555              
556              [activityIndicatorView removeFromSuperviewAndRelease];
557              [self.navigationController popViewControllerAnimated:YES];
558              
559              if ((self.folder.parent && !self.folder.parent.objectsAndFoldersCount) ||
560                  (!self.folder.parent && !self.container.rootFolder.objectsAndFoldersCount)) {
561                  self.parentFolderViewController.folder = self.parentFolderViewController.folder;
562              } else if ((self.folder.parent && self.folder.parent.objectsAndFoldersCount) ||
563                         (!self.folder.parent && self.container.rootFolder.objectsAndFoldersCount)) {
564                  [self.parentFolderViewController.tableView selectRowAtIndexPath:selectedFolderIndexPath
565                                                                         animated:YES
566                                                                   scrollPosition:UITableViewScrollPositionNone];
567                  if (self.parentFolderViewController.searchDisplayController.active &&
568                      self.parentFolderViewController.searchFilter && self.parentFolderViewController.searchFilter.length)
569                      [self.parentFolderViewController.searchDisplayController.searchResultsTableView selectRowAtIndexPath:selectedFolderIndexPath
570                                                                                                                  animated:YES
571                                                                                                            scrollPosition:UITableViewScrollPositionNone];
572                  [NSTimer scheduledTimerWithTimeInterval:0.75 target:self selector:@selector(deleteFolderRow) userInfo:nil repeats:NO];
573              }
574              if ((UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) && self.folder.parent)
575                  [self.parentFolderViewController setDetailViewController];
576              [object release];
577          }
578          failure:^(OpenStackRequest *request) {
579              [activityIndicatorView removeFromSuperviewAndRelease];
580              [self alert:@"There was a problem deleting this folder." request:request];
581              [object release];
582          }];        
583     }
584 }
585
586 @end