2 // FolderViewController.m
5 // Created by Mike Mayo on 12/15/10.
6 // The OpenStack project is provided under the Apache 2.0 license.
9 #import "FolderViewController.h"
10 #import "OpenStackAccount.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"
28 #import "APICallback.h"
29 #import "OpenStackAppDelegate.h"
30 #import <MobileCoreServices/MobileCoreServices.h>
31 #import "ComputeModel.h"
33 @implementation FolderViewController
35 @synthesize account, container, folder, name, containersViewController, selectedContainerIndexPath, contentsLoaded, parentFolderViewController, selectedFolderIndexPath, tableView, needsRefreshing, folderHasBeenRemoved, refreshWhenAppeared, folderDetailVC, selectedObjectViewController, refreshButton;
36 @synthesize searchBar, searchDisplayController, searchFilter;
38 #pragma mark - View lifecycle
45 searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:self.searchBar contentsController:self];
46 searchDisplayController.delegate = self;
47 searchDisplayController.searchResultsDataSource = self;
48 searchDisplayController.searchResultsDelegate = self;
51 - (void)viewWillAppear:(BOOL)animated {
52 [super viewWillAppear:animated];
53 if (self.name && self.name.length) {
54 self.navigationItem.title = self.name;
56 self.navigationItem.title = self.container.name;
60 - (void)viewDidAppear:(BOOL)animated {
61 [super viewDidAppear:animated];
63 if (folderHasBeenRemoved) {
65 self.parentFolderViewController.needsRefreshing = YES;
66 [self.navigationController popViewControllerAnimated:YES];
68 [self refreshButtonPressed:nil];
70 } else if (self.needsRefreshing) {
71 self.parentFolderViewController.needsRefreshing = YES;
72 if (refreshWhenAppeared) {
73 [self refreshButtonPressed:nil];
74 refreshWhenAppeared = NO;
76 if (account.shared && !folder.objectsAndFoldersCount) {
77 [self.navigationController popViewControllerAnimated:YES];
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];
91 #pragma mark - Memory management
97 [containersViewController release];
98 [selectedContainerIndexPath release];
99 [parentFolderViewController release];
100 [selectedFolderIndexPath release];
101 [refreshButton release];
103 [searchDisplayController release];
104 [searchFilter release];
108 #pragma mark - Internal
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);
118 self.tableView.tableHeaderView = nil;
119 self.searchBar.hidden = YES;
123 - (void)reloadFolderViewControllers {
124 NSArray *viewControllers = [self.navigationController viewControllers];
126 int rootFolderControllerIndex = [viewControllers indexOfObject:self.containersViewController] + 1;
127 FolderViewController *rootFolderViewController = [viewControllers objectAtIndex:rootFolderControllerIndex];
128 rootFolderViewController.folder = self.container.rootFolder;
130 for (int i = rootFolderControllerIndex + 1; i < [viewControllers count]; i++) {
131 FolderViewController *folderViewController = [viewControllers objectAtIndex:i];
132 Folder *parentFolder = folderViewController.parentFolderViewController.folder;
134 folderViewController.folder = [parentFolder.folders objectForKey:folderViewController.folder.name];
135 if (!folderViewController.folder)
136 folderViewController.folderHasBeenRemoved = YES;
138 if (!self.folder || (account.shared && !folder.objectsAndFoldersCount)) {
139 if (needsRefreshing && self.parentFolderViewController) {
140 self.parentFolderViewController.needsRefreshing = YES;
142 [self.navigationController popViewControllerAnimated:YES];
143 } else if ((UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) && account.shared) {
144 [self setDetailViewController];
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];
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;
167 - (NSArray *)searchResults {
168 return [self.folder sortedContentsUsingFilter:self.searchFilter
169 andScope:[self.searchBar.scopeButtonTitles objectAtIndex:self.searchBar.selectedScopeButtonIndex]];
172 #pragma mark - Properties
174 - (UISearchBar *)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;
188 - (void)setFolder:(Folder *)aFolder {
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];
195 self.selectedObjectViewController.object = newObject;
196 // We don't set nil otherwise, this will be done in reloadData, when setDetailViewController is called.
201 #pragma mark - Actions
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];
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
218 scrollPosition:UITableViewScrollPositionNone];
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;
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;
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
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];
258 #pragma mark - UIScrollViewDelegate
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;
269 #pragma mark - UITableViewDataSource
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) {
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;
289 aTableView.scrollEnabled = NO;
290 aTableView.allowsSelection = NO;
291 return aTableView.frame.size.height;
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;
305 if ([self.container.rootFolder isEqual:self.folder]) {
306 return [self tableView:aTableView
307 emptyCellWithImage:[UIImage imageNamed:@"empty-files.png"]
309 subtitle:noFoldersSubtitle];
311 return [self tableView:aTableView
312 emptyCellWithImage:[UIImage imageNamed:@"empty-files.png"]
314 subtitle:noFoldersSubtitle
315 deleteButtonTitle:deleteFolderButtonTitle
316 deleteButtonSelector:deleteButtonSelector];
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];
323 cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
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;
333 cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
336 cell.imageView.image = [UIImage imageNamed:@"folder-icon.png"];
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, ";
344 NSString *objectString = @"";
345 if (cellFolder.objects.count != 1) {
346 objectString = [NSString stringWithFormat:@"%u objects", cellFolder.objects.count];
348 objectString = @"1 object";
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;
358 cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
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];
370 if (cellObject.lastModifiedString) {
371 cell.detailTextLabel.text = [NSString stringWithFormat:@"%@, %@", cellObject.humanizedBytes, cellObject.lastModifiedString];
373 cell.detailTextLabel.text = cellObject.humanizedBytes;
381 #pragma mark - UITableViewDelegate
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;
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];
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;
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];
425 [aTableView deselectRowAtIndexPath:indexPath animated:YES];
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];
442 #pragma mark - UISearchDisplayDelegate
444 - (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
445 self.searchFilter = searchString;
450 - (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption {
455 - (void)searchDisplayControllerWillEndSearch:(UISearchDisplayController *)controller {
456 self.searchFilter = nil;
460 #pragma mark - Button Handlers
462 - (IBAction)homeButtonPressed:(id)sender {
463 [self.navigationController popToViewController:containersViewController.accountHomeViewController animated:YES];
466 - (IBAction)refreshButtonPressed:(id)sender {
467 activityIndicatorView = [[ActivityIndicatorView alloc] initWithFrame:[ActivityIndicatorView frameForText:@"Loading..."] text:@"Loading..."];
468 [activityIndicatorView addToView:self.view];
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)
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];
490 [[NSNotificationCenter defaultCenter] removeObserver:successObserver];
492 failureObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"getObjectsFailed"
493 object:self.container
494 queue:[NSOperationQueue mainQueue]
495 usingBlock:^(NSNotification* notification)
497 needsRefreshing = NO;
499 [activityIndicatorView removeFromSuperviewAndRelease];
500 [self alert:@"Error" message:@"Failed to retrieve files from server"];
501 [[NSNotificationCenter defaultCenter] removeObserver:failureObserver];
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];
518 [self presentModalViewControllerWithNavigation:vc animated:YES];
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."
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];
532 [deleteActionSheet showInView:self.view];
536 #pragma mark - UIActionSheetDelegate
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];
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];
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];
552 [self.container.rootFolder removeFolder:self.folder];
554 [self.account persist];
556 [activityIndicatorView removeFromSuperviewAndRelease];
557 [self.navigationController popViewControllerAnimated:YES];
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
566 scrollPosition:UITableViewScrollPositionNone];
567 if (self.parentFolderViewController.searchDisplayController.active &&
568 self.parentFolderViewController.searchFilter && self.parentFolderViewController.searchFilter.length)
569 [self.parentFolderViewController.searchDisplayController.searchResultsTableView selectRowAtIndexPath:selectedFolderIndexPath
571 scrollPosition:UITableViewScrollPositionNone];
572 [NSTimer scheduledTimerWithTimeInterval:0.75 target:self selector:@selector(deleteFolderRow) userInfo:nil repeats:NO];
574 if ((UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) && self.folder.parent)
575 [self.parentFolderViewController setDetailViewController];
578 failure:^(OpenStackRequest *request) {
579 [activityIndicatorView removeFromSuperviewAndRelease];
580 [self alert:@"There was a problem deleting this folder." request:request];