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.
// The OpenStack project is provided under the Apache 2.0 license.
//
-#import <UIKit/UIKit.h>
-
@class ContainersViewController, OpenStackAccount;
@interface AddContainerViewController : UITableViewController <UITextFieldDelegate> {
- UITextField *nameTextField;
+ UITextField *textField;
ContainersViewController *containersViewController;
OpenStackAccount *account;
}
#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";
[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;
}
}
- (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
Container *container;
Folder *folder;
FolderViewController *folderViewController;
- BOOL saving;
- id successObserver;
- id failureObserver;
BOOL allowOverwrite;
}
#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";
[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
@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;
#import "APICallback.h"
#import "Provider.h"
#import "AccountHomeViewController.h"
+#import "ActivityIndicatorView.h"
@implementation ContainersViewController
#pragma mark - Memory management
- (void)dealloc {
- self.accountUsageInfo = nil;
[tableView release];
[account release];
[containerDetailViewController release];
#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];
#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
}
- (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];
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"])
}
} 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];
}