2 // ContainersViewController.m
5 // Created by Mike Mayo on 12/7/10.
6 // The OpenStack project is provided under the Apache 2.0 license.
9 #import "NSObject+Conveniences.h"
10 #import "ContainersViewController.h"
11 #import "OpenStackAccount.h"
13 #import "AddContainerViewController.h"
14 #import "UIViewController+Conveniences.h"
15 #import "FolderViewController.h"
16 #import "ContainerDetailViewController.h"
17 #import "AccountManager.h"
18 #import "OpenStackAppDelegate.h"
19 #import "RootViewController.h"
20 #import "APICallback.h"
22 #import "AccountHomeViewController.h"
24 @implementation ContainersViewController
26 @synthesize tableView, account, accountUsageInfo, accountHomeViewController, containerDetailViewController;
28 #pragma mark - View lifecycle
32 self.navigationItem.title = @"Containers";
37 - (void)viewWillAppear:(BOOL)animated {
38 [super viewWillAppear:animated];
40 if ([self.account.containers count] == 0) {
41 self.tableView.allowsSelection = NO;
42 self.tableView.scrollEnabled = NO;
43 [self.tableView reloadData];
45 if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
46 if ([self.account.containers count] == 0 ) {
47 NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
48 [self.tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
49 [self tableView:self.tableView didSelectRowAtIndexPath:indexPath];
50 } else if ([self.tableView indexPathForSelectedRow].row == 0 && [self.tableView indexPathForSelectedRow].section == 0) {
51 ContainerDetailViewController *vc = [[ContainerDetailViewController alloc] initWithNibName:@"ContainerDetailViewController" bundle:nil];
52 [self presentPrimaryViewController:vc];
57 [self refreshButtonPressed:nil];
60 #pragma mark - Memory management
63 [accountUsageInfo release];
66 [containerDetailViewController release];
70 #pragma mark - Internal
72 - (void)enableRefreshButton {
73 refreshButton.enabled = YES;
74 [self hideToolbarActivityMessage];
75 if (!account.sharingAccount)
76 [self showToolbarInfoMessage:accountUsageInfo];
79 - (void)createContainerWithName:(NSString *)containerName {
80 [self hideToolbarInfoMessage];
81 [self showToolbarActivityMessage:@"Creating container..."];
82 Container *container = [[Container alloc] init];
83 container.name = containerName;
84 [[self.account.manager createContainer:container]
85 success:^(OpenStackRequest *request) {
86 [self hideToolbarActivityMessage];
87 if (!account.sharingAccount)
88 [self showToolbarInfoMessage:accountUsageInfo];
89 [self.tableView reloadData];
91 failure:^(OpenStackRequest *request) {
92 [self hideToolbarActivityMessage];
93 if (!account.sharingAccount)
94 [self showToolbarInfoMessage:accountUsageInfo];
95 [self alert:@"There was a problem creating your container." request:request];
100 #pragma mark - Button Handlers
102 - (void)addButtonPressed:(id)sender {
103 AddContainerViewController *vc = [[AddContainerViewController alloc] initWithNibName:@"AddContainerViewController" bundle:nil];
104 vc.containersViewController = self;
105 vc.account = account;
106 if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
107 OpenStackAppDelegate *app = [[UIApplication sharedApplication] delegate];
108 [app.rootViewController.popoverController dismissPopoverAnimated:YES];
110 [self presentModalViewControllerWithNavigation:vc];
114 - (IBAction)homeButtonPressed:(id)sender {
115 [self.navigationController popToViewController:accountHomeViewController animated:YES];
118 - (void)refreshButtonPressed:(id)sender {
119 refreshButton.enabled = NO;
120 if (!account.sharingAccount)
121 [self hideToolbarInfoMessage];
122 [self showToolbarActivityMessage:@"Refreshing containers..."];
124 [[self.account.manager getContainers] success:^(OpenStackRequest *request) {
125 self.account.containers = [request containers];
126 self.account.containerCount = [self.account.containers count];
127 self.account.totalBytesUsed = [[request.responseHeaders objectForKey:@"X-Account-Bytes-Used"] longLongValue];
128 self.account.quota = [[request.responseHeaders objectForKey:@"X-Account-Policy-Quota"] longLongValue];
129 self.accountUsageInfo = [NSString stringWithFormat:@"%@ used, %@ available",
130 [NSObject osxStyleHumanizedBytes:self.account.totalBytesUsed],
131 [NSObject osxStyleHumanizedBytes:self.account.quota]];
133 [self.account persist];
134 containersLoaded = YES;
135 [self enableRefreshButton];
136 [self.tableView reloadData];
137 if (!account.shared && !account.sharingAccount) {
138 if (![self.account.containers objectForKey:@"pithos"])
139 [self createContainerWithName:@"pithos"];
140 if (![self.account.containers objectForKey:@"trash"])
141 [self createContainerWithName:@"trash"];
143 } failure:^(OpenStackRequest *request) {
144 containersLoaded = NO;
145 [self enableRefreshButton];
146 if (request.responseStatusCode != 0) {
147 [self alert:@"There was a problem loading your containers." request:request];
152 #pragma mark - UITableViewDataSource
154 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
155 if ([self.account.containers count] == 0) {
156 self.tableView.allowsSelection = NO;
157 self.tableView.scrollEnabled = NO;
159 self.tableView.allowsSelection = YES;
160 self.tableView.scrollEnabled = YES;
162 if (!containersLoaded && [self.account.containers count] == 0) {
165 return MAX(1, [account.containers count]);
169 - (CGFloat)tableView:(UITableView *)aTableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
170 if ([account.containers count] == 0) {
171 return aTableView.frame.size.height;
173 return aTableView.rowHeight;
177 - (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
178 if (containersLoaded && [self.account.containers count] == 0) {
179 NSString *noContainersTitle = self.account.shared ? @"No shared containers" : @"No containers";
180 NSString *noContainersSubtitle = self.account.shared ? @"" : @"Tap the + button to create a new container";
181 self.navigationItem.rightBarButtonItem.enabled = !self.account.shared;
183 return [self tableView:tableView emptyCellWithImage:
184 [UIImage imageNamed:@"empty-containers.png"]
185 title:noContainersTitle
186 subtitle:noContainersSubtitle];
188 static NSString *CellIdentifier = @"Cell";
190 UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:CellIdentifier];
192 cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
193 if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
194 cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
196 cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
199 Container *container = [self.account.pithosSortedContainers objectAtIndex:indexPath.row];
200 cell.textLabel.text = container.name;
201 if ([container.name isEqualToString:@"pithos"])
202 cell.imageView.image = [UIImage imageNamed:@"PithosContainerIcon.png"];
203 else if ([container.name isEqualToString:@"trash"])
204 cell.imageView.image = [UIImage imageNamed:@"TrashIcon.png"];
206 cell.imageView.image = [UIImage imageNamed:@"ContainerIcon.png"];
208 if (!self.account.sharingAccount)
209 cell.detailTextLabel.text = [container osxStyleHumanizedSize];
215 #pragma mark - UITableViewDelegate
217 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
218 Container *container = nil;
219 if ([account.containers count] > 0) {
220 container = [self.account.pithosSortedContainers objectAtIndex:indexPath.row];
222 FolderViewController *vc = [[FolderViewController alloc] initWithNibName:@"FolderViewController" bundle:nil];
223 vc.account = self.account;
224 vc.container = container;
225 vc.folder = container.rootFolder;
226 vc.containersViewController = self;
227 vc.selectedContainerIndexPath = indexPath;
228 [self.navigationController pushViewController:vc animated:YES];
230 [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
233 if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
234 ContainerDetailViewController *vc = [[ContainerDetailViewController alloc] initWithNibName:@"ContainerDetailViewController" bundle:nil];
235 vc.account = self.account;
236 vc.container = container;
237 vc.containersViewController = self;
238 vc.selectedContainerIndexPath = indexPath;
239 [self presentPrimaryViewController:vc];
240 self.containerDetailViewController = vc;
245 - (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath {
246 Container *container = nil;
247 if ([account.containers count] > 0) {
248 container = [self.account.pithosSortedContainers objectAtIndex:indexPath.row];
250 ContainerDetailViewController *vc = [[ContainerDetailViewController alloc] initWithNibName:@"ContainerDetailViewController" bundle:nil];
251 vc.account = self.account;
252 vc.container = container;
253 vc.containersViewController = self;
254 vc.selectedContainerIndexPath = indexPath;
255 [self.navigationController pushViewController:vc animated:YES];