From 7d96b67dbde0aeb8aa24ddce8de6a9eb1d55dc0c Mon Sep 17 00:00:00 2001 From: Miltiadis Vasilakis Date: Thu, 6 Dec 2012 21:44:32 +0200 Subject: [PATCH] Show activity indicator views when creating or refreshing containers Show activity indicator view, in the view responsible for the container creation or refresh, instead of a toolbar activity message always in the containers view controller. --- Classes/AddContainerViewController.h | 4 +- Classes/AddContainerViewController.m | 88 ++++++------- Classes/AddFolderViewController.h | 3 - Classes/AddFolderViewController.m | 225 ++++++++++++++++------------------ Classes/ContainersViewController.h | 2 +- Classes/ContainersViewController.m | 55 ++++----- 6 files changed, 170 insertions(+), 207 deletions(-) diff --git a/Classes/AddContainerViewController.h b/Classes/AddContainerViewController.h index e71182a..a1b2089 100755 --- a/Classes/AddContainerViewController.h +++ b/Classes/AddContainerViewController.h @@ -6,12 +6,10 @@ // The OpenStack project is provided under the Apache 2.0 license. // -#import - @class ContainersViewController, OpenStackAccount; @interface AddContainerViewController : UITableViewController { - UITextField *nameTextField; + UITextField *textField; ContainersViewController *containersViewController; OpenStackAccount *account; } diff --git a/Classes/AddContainerViewController.m b/Classes/AddContainerViewController.m index 8f66d2d..d462c06 100755 --- a/Classes/AddContainerViewController.m +++ b/Classes/AddContainerViewController.m @@ -14,19 +14,18 @@ #import "AccountManager.h" #import "RSTextFieldCell.h" #import "APICallback.h" - +#import "ActivityIndicatorView.h" @implementation AddContainerViewController @synthesize containersViewController, account; +#pragma mark - View lifecycle + - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation { return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) || (toInterfaceOrientation == UIInterfaceOrientationPortrait); } -#pragma mark - -#pragma mark View lifecycle - - (void)viewDidLoad { [super viewDidLoad]; self.navigationItem.title = @"Add Container"; @@ -34,13 +33,21 @@ [self addSaveButton]; } -#pragma mark - -#pragma mark Table view data source +- (void)viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; + [textField becomeFirstResponder]; +} + +#pragma mark - Memory management -- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { - return 1; +- (void)dealloc { + [containersViewController release]; + [account release]; + [super dealloc]; } +#pragma mark - UITableViewDataSource + - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return 1; } @@ -50,65 +57,50 @@ } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - - static NSString *CellIdentifier = @"Cell"; - - RSTextFieldCell *cell = (RSTextFieldCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; + static NSString *cellIdentifier = @"ContainerNameCell"; + RSTextFieldCell *cell = (RSTextFieldCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier]; if (cell == nil) { - cell = [[[RSTextFieldCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease]; - cell.selectionStyle = UITableViewCellSelectionStyleNone; + cell = [[[RSTextFieldCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifier] autorelease]; cell.modalPresentationStyle = UIModalPresentationFormSheet; - nameTextField = cell.textField; - nameTextField.delegate = self; - [nameTextField becomeFirstResponder]; + textField = cell.textField; + textField.delegate = self; + textField.clearButtonMode = UITextFieldViewModeWhileEditing; } - cell.textLabel.text = @"Name"; - return cell; } -#pragma mark - -#pragma mark Button Handlers +#pragma mark - UITextFieldDelegate + +- (BOOL)textFieldShouldReturn:(UITextField *)textField { + [self saveButtonPressed:nil]; + return NO; +} + +#pragma mark - Button handlers - (void)saveButtonPressed:(id)sender { - if ([nameTextField.text isEqualToString:@""]) { - [self alert:nil message:@"Please enter a name."]; - [nameTextField becomeFirstResponder]; + if ([textField.text isEqualToString:@""]) { + [self alert:@"Container Name Required" message:@"Please enter a container name."]; } else { - [self.containersViewController showToolbarActivityMessage:@"Creating container..."]; - + [textField resignFirstResponder]; + __block ActivityIndicatorView *activityIndicatorView = [ActivityIndicatorView activityIndicatorViewWithText:@"Creating container..." + andAddToView:self.view]; Container *container = [[Container alloc] init]; - container.name = nameTextField.text; + container.name = textField.text; [[self.account.manager createContainer:container] success:^(OpenStackRequest *request) { - [self.containersViewController showToolbarInfoMessage:self.containersViewController.accountUsageInfo]; [self.containersViewController.tableView reloadData]; + [activityIndicatorView removeFromSuperview]; + [self dismissModalViewControllerAnimated:YES]; + [container release]; } failure:^(OpenStackRequest *request) { - [self.containersViewController showToolbarInfoMessage:self.containersViewController.accountUsageInfo]; + [activityIndicatorView removeFromSuperview]; [self.containersViewController alert:@"There was a problem creating your container." request:request]; + [container release]; }]; - [container release]; - [self dismissModalViewControllerAnimated:YES]; } } -#pragma mark - -#pragma mark Text Field Delegate - -- (BOOL)textFieldShouldReturn:(UITextField *)textField { - [self saveButtonPressed:nil]; - return NO; -} - -#pragma mark - -#pragma mark Memory management - -- (void)dealloc { - [containersViewController release]; - [account release]; - [super dealloc]; -} - @end diff --git a/Classes/AddFolderViewController.h b/Classes/AddFolderViewController.h index b924533..f542981 100755 --- a/Classes/AddFolderViewController.h +++ b/Classes/AddFolderViewController.h @@ -14,9 +14,6 @@ Container *container; Folder *folder; FolderViewController *folderViewController; - BOOL saving; - id successObserver; - id failureObserver; BOOL allowOverwrite; } diff --git a/Classes/AddFolderViewController.m b/Classes/AddFolderViewController.m index 4172105..b8f8781 100755 --- a/Classes/AddFolderViewController.m +++ b/Classes/AddFolderViewController.m @@ -18,18 +18,16 @@ #import "FolderViewController.h" #import "APICallback.h" - @implementation AddFolderViewController @synthesize account, container, folder, folderViewController; +#pragma mark - View lifecycle + - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation { return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) || (toInterfaceOrientation == UIInterfaceOrientationPortrait); } -#pragma mark - -#pragma mark View lifecycle - - (void)viewDidLoad { [super viewDidLoad]; self.navigationItem.title = @"Add Folder"; @@ -41,149 +39,132 @@ [textField becomeFirstResponder]; } -#pragma mark - -#pragma mark Save Button +#pragma mark - Memory management -- (void)saveButtonPressed:(id)sender { - if (!saving) { - if ([textField.text isEqualToString:@""]) { - [self alert:@"Folder Name Required" message:@"Please enter a folder name."]; - } else { - [textField resignFirstResponder]; - NSString *objectName; - BOOL objectNameHasTrailingSlash = [textField.text hasSuffix:@"/"]; - NSUInteger indexOfFirstSlash = [textField.text rangeOfString:@"/"].location; - - if ((!objectNameHasTrailingSlash && indexOfFirstSlash != NSNotFound) || - (objectNameHasTrailingSlash && indexOfFirstSlash < textField.text.length - 1)) { - [self alert:@"Invalid folder name" message:@"'/' characters are only allowed at the end of folder names"]; - return; - } - - if (folder && folder.name) { - objectName = [NSString stringWithFormat:@"%@/%@", [folder fullPath], textField.text]; - } else { - objectName = textField.text; - } - - if ([folderViewController.folder.folders objectForKey:objectName] && !allowOverwrite) { - NSString *alertMessage = [NSString stringWithFormat:@"An object with path '%@' in the container '%@' already exists, do you want to replace it?",objectName, folderViewController.container.name]; - NSString *alertTitle = @"Apply changes"; - UIAlertView *alert = [[UIAlertView alloc] initWithTitle:alertTitle - message:alertMessage - delegate:self - cancelButtonTitle:@"Cancel" - otherButtonTitles:@"OK", nil]; - [alert show]; - [alert release]; - return; - } - - StorageObject *object = [[StorageObject alloc] init]; - object.name = object.fullPath = objectName; - object.data = [NSData data]; - object.contentType = @"application/directory"; - - __block ActivityIndicatorView *activityIndicatorView = [ActivityIndicatorView activityIndicatorViewWithText:@"Adding folder..." - andAddToView:self.view]; - [[self.account.manager writeObject:self.container object:object downloadProgressDelegate:nil] - success:^(OpenStackRequest *request) { - Folder *newFolder = [[Folder alloc] init]; - if (objectNameHasTrailingSlash) - object.name = [object.name substringToIndex:object.name.length - 1]; - newFolder.name = [[object.name componentsSeparatedByString:@"/"] lastObject]; - if (objectNameHasTrailingSlash) - newFolder.name = [newFolder.name stringByAppendingString:@"/"]; - newFolder.parent = folder; - newFolder.sharing = folder.sharing; - BOOL currentFolderIsRoot = NO; - if ([folderViewController.folder isEqual:container.rootFolder]) { - currentFolderIsRoot = YES; - } - [folder addFolder:newFolder]; - folderViewController.folder = folderViewController.folder; - if (currentFolderIsRoot) { - container.count += 1; - container.rootFolder = folder; - [self.account.containers setObject:container forKey:container.name]; - } - if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) - [folderViewController setDetailViewController]; - - allowOverwrite = NO; - [activityIndicatorView removeFromSuperview]; - [self dismissModalViewControllerAnimated:YES]; - [newFolder release]; - [object release]; - - } - failure:^(OpenStackRequest *request) { - allowOverwrite = NO; - [activityIndicatorView removeFromSuperview]; - [self alert:@"There was a problem creating this folder." request:request]; - [object release]; - }]; - } - } +- (void)dealloc { + [account release]; + [container release]; + [folder release]; + [folderViewController release]; + [super dealloc]; } -#pragma mark - -#pragma mark Table view data source - -- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { - return 1; -} +#pragma mark - UITableViewDataSource - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return 1; } -- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section { - return @"If your folder name contains any forward slash characters, multiple folder objects will be created."; -} - - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - static NSString *CellIdentifier = @"FolderNameCell"; - RSTextFieldCell *cell = (RSTextFieldCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; + static NSString *cellIdentifier = @"FolderNameCell"; + RSTextFieldCell *cell = (RSTextFieldCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier]; if (cell == nil) { - cell = [[[RSTextFieldCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease]; + cell = [[[RSTextFieldCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifier] autorelease]; cell.modalPresentationStyle = UIModalPresentationFormSheet; textField = cell.textField; textField.delegate = self; textField.clearButtonMode = UITextFieldViewModeWhileEditing; - } + } cell.textLabel.text = @"Name"; return cell; } -#pragma mark - Alertview delegate - -- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex -{ - if (buttonIndex == 1) { - allowOverwrite = YES; - [self saveButtonPressed:nil]; - } -} - - -#pragma mark - -#pragma mark Text Field Delegate +#pragma mark - UITextFieldDelegate - (BOOL)textFieldShouldReturn:(UITextField *)textField { [self saveButtonPressed:nil]; return NO; } -#pragma mark - -#pragma mark Memory management +#pragma mark - UIAlertViewDelegate -- (void)dealloc { - [account release]; - [container release]; - [folder release]; - [folderViewController release]; - [super dealloc]; +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { + if (buttonIndex == 1) { + allowOverwrite = YES; + [self saveButtonPressed:nil]; + } +} + +#pragma mark - Button handlers + +- (void)saveButtonPressed:(id)sender { + if ([textField.text isEqualToString:@""]) { + [self alert:@"Folder Name Required" message:@"Please enter a folder name."]; + } else { + [textField resignFirstResponder]; + NSString *objectName; + BOOL objectNameHasTrailingSlash = [textField.text hasSuffix:@"/"]; + NSUInteger indexOfFirstSlash = [textField.text rangeOfString:@"/"].location; + if ((!objectNameHasTrailingSlash && indexOfFirstSlash != NSNotFound) || + (objectNameHasTrailingSlash && indexOfFirstSlash < textField.text.length - 1)) { + [self alert:@"Invalid folder name" message:@"'/' characters are only allowed at the end of folder names"]; + return; + } + + if (folder && folder.name) { + objectName = [NSString stringWithFormat:@"%@/%@", [folder fullPath], textField.text]; + } else { + objectName = textField.text; + } + + if ([folderViewController.folder.folders objectForKey:objectName] && !allowOverwrite) { + NSString *alertMessage = [NSString stringWithFormat:@"An object with path '%@' in the container '%@' already exists, do you want to replace it?", + objectName, folderViewController.container.name]; + NSString *alertTitle = @"Apply changes"; + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:alertTitle + message:alertMessage + delegate:self + cancelButtonTitle:@"Cancel" + otherButtonTitles:@"OK", nil]; + [alert show]; + [alert release]; + return; + } + + StorageObject *object = [[StorageObject alloc] init]; + object.name = object.fullPath = objectName; + object.data = [NSData data]; + object.contentType = @"application/directory"; + + __block ActivityIndicatorView *activityIndicatorView = [ActivityIndicatorView activityIndicatorViewWithText:@"Adding folder..." + andAddToView:self.view]; + [[self.account.manager writeObject:self.container object:object downloadProgressDelegate:nil] + success:^(OpenStackRequest *request) { + Folder *newFolder = [[Folder alloc] init]; + if (objectNameHasTrailingSlash) + object.name = [object.name substringToIndex:object.name.length - 1]; + newFolder.name = [[object.name componentsSeparatedByString:@"/"] lastObject]; + if (objectNameHasTrailingSlash) + newFolder.name = [newFolder.name stringByAppendingString:@"/"]; + newFolder.parent = folder; + newFolder.sharing = folder.sharing; + BOOL currentFolderIsRoot = NO; + if ([folderViewController.folder isEqual:container.rootFolder]) { + currentFolderIsRoot = YES; + } + [folder addFolder:newFolder]; + folderViewController.folder = folderViewController.folder; + if (currentFolderIsRoot) { + container.count += 1; + container.rootFolder = folder; + [self.account.containers setObject:container forKey:container.name]; + } + if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) + [folderViewController setDetailViewController]; + + allowOverwrite = NO; + [activityIndicatorView removeFromSuperview]; + [self dismissModalViewControllerAnimated:YES]; + [newFolder release]; + [object release]; + } + failure:^(OpenStackRequest *request) { + allowOverwrite = NO; + [activityIndicatorView removeFromSuperview]; + [self alert:@"There was a problem creating this folder." request:request]; + [object release]; + }]; + } } @end diff --git a/Classes/ContainersViewController.h b/Classes/ContainersViewController.h index f389ffe..a1a00b7 100755 --- a/Classes/ContainersViewController.h +++ b/Classes/ContainersViewController.h @@ -24,7 +24,7 @@ @property (nonatomic, retain) IBOutlet UITableView *tableView; @property (nonatomic, retain) OpenStackAccount *account; -@property (nonatomic, retain) NSString *accountUsageInfo; +@property (nonatomic, readonly) NSString *accountUsageInfo; @property (nonatomic, assign) AccountHomeViewController *accountHomeViewController; @property (nonatomic, retain) ContainerDetailViewController *containerDetailViewController; diff --git a/Classes/ContainersViewController.m b/Classes/ContainersViewController.m index 12e9695..4a64ae2 100755 --- a/Classes/ContainersViewController.m +++ b/Classes/ContainersViewController.m @@ -20,6 +20,7 @@ #import "APICallback.h" #import "Provider.h" #import "AccountHomeViewController.h" +#import "ActivityIndicatorView.h" @implementation ContainersViewController @@ -60,7 +61,6 @@ #pragma mark - Memory management - (void)dealloc { - self.accountUsageInfo = nil; [tableView release]; [account release]; [containerDetailViewController release]; @@ -69,22 +69,19 @@ #pragma mark - Internal -- (void)enableRefreshButton { - refreshButton.enabled = YES; - [self showToolbarInfoMessage:self.accountUsageInfo]; -} - - (void)createContainerWithName:(NSString *)containerName { - [self showToolbarActivityMessage:@"Creating container..."]; + __block ActivityIndicatorView *activityIndicatorView = [ActivityIndicatorView activityIndicatorViewWithText:@"Creating container..." + andAddToView:self.view]; + Container *container = [[Container alloc] init]; container.name = containerName; [[self.account.manager createContainer:container] success:^(OpenStackRequest *request) { - [self showToolbarInfoMessage:self.accountUsageInfo]; + [activityIndicatorView removeFromSuperview]; [self.tableView reloadData]; } failure:^(OpenStackRequest *request) { - [self showToolbarInfoMessage:self.accountUsageInfo]; + [activityIndicatorView removeFromSuperview]; [self alert:@"There was a problem creating your container." request:request]; }]; [container release]; @@ -93,22 +90,19 @@ #pragma mark - Properties - (NSString *)accountUsageInfo { - if (self.account.sharingAccount || (!self.account.bytesUsed && !self.account.policyQuota)) { - [accountUsageInfo release]; - accountUsageInfo = nil; - } else if (!accountUsageInfo) { - if (self.account.bytesUsed && self.account.policyQuota) { - accountUsageInfo = [NSString stringWithFormat:@"%@ used, %@ available", - [NSObject osxStyleHumanizedBytesNumber:self.account.bytesUsed], - [NSObject osxStyleHumanizedBytesNumber:self.account.policyQuota]]; - } else if (self.account.bytesUsed) { - accountUsageInfo = [NSString stringWithFormat:@"%@ used", [NSObject osxStyleHumanizedBytesNumber:self.account.bytesUsed]]; - } else if (self.account.policyQuota) { - accountUsageInfo = [NSString stringWithFormat:@"%@ available", [NSObject osxStyleHumanizedBytesNumber:self.account.policyQuota]]; - } - [accountUsageInfo retain]; + if (self.account.sharingAccount) + return nil; + if (self.account.bytesUsed && self.account.policyQuota) { + return [NSString stringWithFormat:@"%@ used, %@ available", + [NSObject osxStyleHumanizedBytesNumber:self.account.bytesUsed], + [NSObject osxStyleHumanizedBytesNumber:self.account.policyQuota]]; + } else if (self.account.bytesUsed) { + return [NSString stringWithFormat:@"%@ used", [NSObject osxStyleHumanizedBytesNumber:self.account.bytesUsed]]; + } else if (self.account.policyQuota) { + return [NSString stringWithFormat:@"%@ available", [NSObject osxStyleHumanizedBytesNumber:self.account.policyQuota]]; + } else { + return nil; } - return accountUsageInfo; } #pragma mark - Button Handlers @@ -130,9 +124,8 @@ } - (void)refreshButtonPressed:(id)sender { - refreshButton.enabled = NO; - [self showToolbarActivityMessage:@"Refreshing containers..."]; - + __block ActivityIndicatorView *activityIndicatorView = [ActivityIndicatorView activityIndicatorViewWithText:@"Loading..." + andAddToView:self.view]; [[self.account.manager getContainers] success:^(OpenStackRequest *request) { self.account.containers = [request containers]; self.account.containerCount = [self.account.containers count]; @@ -142,11 +135,12 @@ NSString *policyQuotaString = [request.responseHeaders objectForKey:@"X-Account-Policy-Quota"]; self.account.policyQuota = (policyQuotaString ? [NSNumber numberWithUnsignedLongLong:strtoull([policyQuotaString UTF8String], NULL, 0)] : nil); - self.accountUsageInfo = nil; [self.account persist]; containersLoaded = YES; - [self enableRefreshButton]; + + [activityIndicatorView removeFromSuperview]; + [self showToolbarInfoMessage:self.accountUsageInfo]; [self.tableView reloadData]; if (!account.shared && !account.sharingAccount) { if (![self.account.containers objectForKey:@"pithos"]) @@ -156,7 +150,8 @@ } } failure:^(OpenStackRequest *request) { containersLoaded = NO; - [self enableRefreshButton]; + [activityIndicatorView removeFromSuperview]; + [self showToolbarInfoMessage:self.accountUsageInfo]; if (request.responseStatusCode != 0) { [self alert:@"There was a problem loading your containers." request:request]; } -- 1.7.10.4