980cb64d103da1013d4ef8f78c1a5bbbf9d93e44
[pithos-ios] / Classes / ContainersViewController.m
1 //
2 //  ContainersViewController.m
3 //  OpenStack
4 //
5 //  Created by Mike Mayo on 12/7/10.
6 //  The OpenStack project is provided under the Apache 2.0 license.
7 //
8
9 #import "NSObject+Conveniences.h"
10 #import "ContainersViewController.h"
11 #import "OpenStackAccount.h"
12 #import "Container.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"
21 #import "Provider.h"
22 #import "AccountHomeViewController.h"
23
24 @implementation ContainersViewController
25
26 @synthesize tableView, account, accountUsageInfo, accountHomeViewController, containerDetailViewController;
27
28 #pragma mark - View lifecycle
29
30 - (void)viewDidLoad {
31     [super viewDidLoad];
32     self.navigationItem.title = @"Containers";
33     [self addAddButton]; 
34     [self addHomeButton];
35 }
36
37 - (void)viewWillAppear:(BOOL)animated {
38     [super viewWillAppear:animated];
39         
40     if ([self.account.containers count] == 0) {
41         self.tableView.allowsSelection = NO;
42         self.tableView.scrollEnabled = NO;
43         [self.tableView reloadData];        
44     }   
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];
53             [vc release]; 
54         }
55     }
56     
57     [self refreshButtonPressed:nil];
58 }
59
60 #pragma mark - Memory management
61
62 - (void)dealloc {
63     [accountUsageInfo release];
64     [tableView release];
65     [account release];
66     [containerDetailViewController release];
67     [super dealloc];
68 }
69
70 #pragma mark - Internal
71
72 - (void)enableRefreshButton {
73     refreshButton.enabled = YES;
74     [self hideToolbarActivityMessage];
75     if (!account.sharingAccount)
76         [self showToolbarInfoMessage:accountUsageInfo];
77 }
78
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];
90      }
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];
96      }];
97     [container release];
98 }
99
100 #pragma mark - Button Handlers
101
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];
109     }
110     [self presentModalViewControllerWithNavigation:vc];
111     [vc release];
112 }
113
114 - (IBAction)homeButtonPressed:(id)sender {
115     [self.navigationController popToViewController:accountHomeViewController animated:YES];
116 }
117
118 - (void)refreshButtonPressed:(id)sender {
119     refreshButton.enabled = NO;
120     if (!account.sharingAccount)
121         [self hideToolbarInfoMessage];
122     [self showToolbarActivityMessage:@"Refreshing containers..."];
123     
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]];
132                                 
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"];
142         }
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];
148         }
149     }];
150 }
151
152 #pragma mark - UITableViewDataSource
153
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;
158     } else {
159         self.tableView.allowsSelection = YES;
160         self.tableView.scrollEnabled = YES;
161     }
162     if (!containersLoaded && [self.account.containers count] == 0) {
163         return 0;
164     } else {
165         return MAX(1, [account.containers count]);    
166     }
167 }
168
169 - (CGFloat)tableView:(UITableView *)aTableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
170     if ([account.containers count] == 0) {
171         return aTableView.frame.size.height;
172     } else {
173         return aTableView.rowHeight;
174     }
175 }
176
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;
182         
183         return [self tableView:tableView emptyCellWithImage:
184                 [UIImage imageNamed:@"empty-containers.png"]
185                          title:noContainersTitle
186                       subtitle:noContainersSubtitle];
187     } else {   
188         static NSString *CellIdentifier = @"Cell";
189         
190         UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:CellIdentifier];
191         if (cell == nil) {
192             cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
193             if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
194                 cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
195             } else {
196                 cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
197             }
198         }
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"];
205         else
206             cell.imageView.image = [UIImage imageNamed:@"ContainerIcon.png"];
207                                     
208         if (!self.account.sharingAccount)
209             cell.detailTextLabel.text = [container osxStyleHumanizedSize];
210         
211         return cell;
212     }
213 }
214
215 #pragma mark - UITableViewDelegate
216
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];
221
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];
229         [vc release];
230         [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
231     }
232     
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;
241         [vc release];
242     }
243 }
244
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];
249     }
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];
256     [vc release];
257 }
258
259 @end