root / Classes / ContainersViewController.m @ 54fd5c36
History | View | Annotate | Download (11.9 kB)
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 "GetCDNContainersRequest.h" |
22 |
#import "Provider.h" |
23 |
#import "AccountHomeViewController.h" |
24 |
|
25 |
|
26 |
@implementation ContainersViewController |
27 |
|
28 |
@synthesize tableView, account, accountUsageInfo, accountHomeViewController, containerDetailViewController; |
29 |
|
30 |
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation { |
31 |
return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) || (toInterfaceOrientation == UIInterfaceOrientationPortrait); |
32 |
} |
33 |
|
34 |
#pragma mark - |
35 |
#pragma mark View lifecycle |
36 |
|
37 |
- (void)viewDidLoad { |
38 |
[super viewDidLoad]; |
39 |
self.navigationItem.title = @"Containers"; |
40 |
[self addAddButton]; |
41 |
[self addHomeButton]; |
42 |
|
43 |
if (!account.shared && !account.sharingAccount && containersLoaded) { |
44 |
if (![self.account.containers objectForKey:@"pithos"]) |
45 |
[self createContainerWithName:@"pithos"]; |
46 |
if (![self.account.containers objectForKey:@"trash"]) |
47 |
[self createContainerWithName:@"trash"]; |
48 |
} |
49 |
|
50 |
} |
51 |
|
52 |
- (void)viewWillAppear:(BOOL)animated { |
53 |
[super viewWillAppear:animated]; |
54 |
|
55 |
if ([self.account.containers count] == 0) { |
56 |
self.tableView.allowsSelection = NO; |
57 |
self.tableView.scrollEnabled = NO; |
58 |
[self.tableView reloadData]; |
59 |
} |
60 |
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { |
61 |
if ([self.account.containers count] == 0 ) { |
62 |
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0]; |
63 |
[self.tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone]; |
64 |
[self tableView:self.tableView didSelectRowAtIndexPath:indexPath]; |
65 |
} |
66 |
else if ([self.tableView indexPathForSelectedRow].row == 0 && [self.tableView indexPathForSelectedRow].section == 0) { |
67 |
ContainerDetailViewController *vc = [[ContainerDetailViewController alloc] initWithNibName:@"ContainerDetailViewController" bundle:nil]; |
68 |
[self presentPrimaryViewController:vc]; |
69 |
[vc release]; |
70 |
} |
71 |
} |
72 |
|
73 |
if (!containersLoaded && [self.account.containers count] == 0) { |
74 |
[self refreshButtonPressed:nil]; |
75 |
} |
76 |
} |
77 |
|
78 |
- (void)viewDidDisappear:(BOOL)animated { |
79 |
[super viewDidDisappear:animated]; |
80 |
} |
81 |
|
82 |
#pragma mark - |
83 |
#pragma mark Button Handlers |
84 |
|
85 |
- (void)addButtonPressed:(id)sender { |
86 |
AddContainerViewController *vc = [[AddContainerViewController alloc] initWithNibName:@"AddContainerViewController" bundle:nil]; |
87 |
vc.containersViewController = self; |
88 |
vc.account = account; |
89 |
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { |
90 |
vc.modalPresentationStyle = UIModalPresentationFormSheet; |
91 |
OpenStackAppDelegate *app = [[UIApplication sharedApplication] delegate]; |
92 |
if (app.rootViewController.popoverController != nil) { |
93 |
[app.rootViewController.popoverController dismissPopoverAnimated:YES]; |
94 |
} |
95 |
} |
96 |
[self presentModalViewControllerWithNavigation:vc]; |
97 |
[vc release]; |
98 |
} |
99 |
|
100 |
- (IBAction)homeButtonPressed:(id)sender { |
101 |
[self.navigationController popToViewController:accountHomeViewController animated:YES]; |
102 |
} |
103 |
|
104 |
|
105 |
- (void)enableRefreshButton { |
106 |
refreshButton.enabled = YES; |
107 |
[self hideToolbarActivityMessage]; |
108 |
if (!account.sharingAccount) |
109 |
[self showToolbarInfoMessage:accountUsageInfo]; |
110 |
} |
111 |
|
112 |
- (void)refreshButtonPressed:(id)sender { |
113 |
refreshButton.enabled = NO; |
114 |
//BOOL hadZeroContainers = [self.account.containers count] == 0; |
115 |
if (!account.sharingAccount) |
116 |
[self hideToolbarInfoMessage]; |
117 |
[self showToolbarActivityMessage:@"Refreshing containers..."]; |
118 |
|
119 |
[[self.account.manager getContainers] success:^(OpenStackRequest *request) { |
120 |
self.account.containers = [request containers]; |
121 |
self.account.containerCount = [self.account.containers count]; |
122 |
self.account.totalBytesUsed = [[request.responseHeaders objectForKey:@"X-Account-Bytes-Used"] longLongValue]; |
123 |
self.account.quota = [[request.responseHeaders objectForKey:@"X-Account-Policy-Quota"] longLongValue]; |
124 |
self.accountUsageInfo = [NSString stringWithFormat:@"%@ used, %@ available", |
125 |
[NSObject osxStyleHumanizedBytes:self.account.totalBytesUsed], |
126 |
[NSObject osxStyleHumanizedBytes:self.account.quota]]; |
127 |
|
128 |
[self.account persist]; |
129 |
containersLoaded = YES; |
130 |
[self enableRefreshButton]; |
131 |
[self.tableView reloadData]; |
132 |
//GetCDNContainersRequest *cdnRequest = [GetCDNContainersRequest request:self.account]; |
133 |
//[cdnRequest startAsynchronous]; |
134 |
|
135 |
} failure:^(OpenStackRequest *request) { |
136 |
containersLoaded = NO; |
137 |
[self enableRefreshButton]; |
138 |
if (request.responseStatusCode != 0) { |
139 |
[self alert:@"There was a problem loading your containers." request:request]; |
140 |
} |
141 |
}]; |
142 |
} |
143 |
|
144 |
#pragma mark - |
145 |
#pragma mark Table view data source |
146 |
|
147 |
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { |
148 |
return 1; |
149 |
} |
150 |
|
151 |
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { |
152 |
if ([self.account.containers count] == 0) { |
153 |
self.tableView.allowsSelection = NO; |
154 |
self.tableView.scrollEnabled = NO; |
155 |
} else { |
156 |
self.tableView.allowsSelection = YES; |
157 |
self.tableView.scrollEnabled = YES; |
158 |
} |
159 |
if (!containersLoaded && [self.account.containers count] == 0) { |
160 |
return 0; |
161 |
} else { |
162 |
return MAX(1, [account.containers count]); |
163 |
} |
164 |
} |
165 |
|
166 |
- (CGFloat)tableView:(UITableView *)aTableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { |
167 |
if ([account.containers count] == 0) { |
168 |
return aTableView.frame.size.height; |
169 |
} else { |
170 |
return aTableView.rowHeight; |
171 |
} |
172 |
} |
173 |
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { |
174 |
if (containersLoaded && [self.account.containers count] == 0) { |
175 |
NSString *noContainersTitle = self.account.shared ? @"No shared containers" : @"No containers"; |
176 |
NSString *noContainersSubtitle = self.account.shared ? @"" : @"Tap the + button to create a new container"; |
177 |
self.navigationItem.rightBarButtonItem.enabled = !self.account.shared; |
178 |
|
179 |
return [self tableView:tableView emptyCellWithImage: |
180 |
[UIImage imageNamed:@"empty-containers.png"] |
181 |
title:noContainersTitle |
182 |
subtitle:noContainersSubtitle]; |
183 |
} else { |
184 |
static NSString *CellIdentifier = @"Cell"; |
185 |
|
186 |
UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:CellIdentifier]; |
187 |
if (cell == nil) { |
188 |
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease]; |
189 |
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { |
190 |
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; |
191 |
} else { |
192 |
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton; |
193 |
} |
194 |
} |
195 |
Container *container = [self.account.pithosSortedContainers objectAtIndex:indexPath.row]; |
196 |
cell.textLabel.text = container.name; |
197 |
if ([container.name isEqualToString:@"pithos"]) |
198 |
cell.imageView.image = [UIImage imageNamed:@"PithosContainerIcon.png"]; |
199 |
else if ([container.name isEqualToString:@"trash"]) |
200 |
cell.imageView.image = [UIImage imageNamed:@"TrashIcon.png"]; |
201 |
else |
202 |
cell.imageView.image = [UIImage imageNamed:@"ContainerIcon.png"]; |
203 |
|
204 |
if (!self.account.sharingAccount) |
205 |
cell.detailTextLabel.text = [container osxStyleHumanizedSize]; |
206 |
|
207 |
return cell; |
208 |
} |
209 |
} |
210 |
|
211 |
#pragma mark - |
212 |
#pragma mark Table view delegate |
213 |
|
214 |
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { |
215 |
Container *container = nil; |
216 |
if ([account.containers count] > 0) { |
217 |
container = [self.account.pithosSortedContainers objectAtIndex:indexPath.row]; |
218 |
|
219 |
FolderViewController *vc = [[FolderViewController alloc] initWithNibName:@"FolderViewController" bundle:nil]; |
220 |
vc.account = self.account; |
221 |
vc.container = container; |
222 |
vc.folder = container.rootFolder; |
223 |
vc.containersViewController = self; |
224 |
vc.selectedContainerIndexPath = indexPath; |
225 |
[self.navigationController pushViewController:vc animated:YES]; |
226 |
[vc release]; |
227 |
[self.tableView deselectRowAtIndexPath:indexPath animated:YES]; |
228 |
} |
229 |
|
230 |
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { |
231 |
ContainerDetailViewController *vc = [[ContainerDetailViewController alloc] initWithNibName:@"ContainerDetailViewController" bundle:nil]; |
232 |
vc.account = self.account; |
233 |
vc.container = container; |
234 |
vc.containersViewController = self; |
235 |
vc.selectedContainerIndexPath = indexPath; |
236 |
[self presentPrimaryViewController:vc]; |
237 |
self.containerDetailViewController = vc; |
238 |
[vc release]; |
239 |
} |
240 |
} |
241 |
|
242 |
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath { |
243 |
Container *container = nil; |
244 |
if ([account.containers count] > 0) { |
245 |
container = [self.account.pithosSortedContainers objectAtIndex:indexPath.row]; |
246 |
} |
247 |
ContainerDetailViewController *vc = [[ContainerDetailViewController alloc] initWithNibName:@"ContainerDetailViewController" bundle:nil]; |
248 |
vc.account = self.account; |
249 |
vc.container = container; |
250 |
vc.containersViewController = self; |
251 |
vc.selectedContainerIndexPath = indexPath; |
252 |
[self.navigationController pushViewController:vc animated:YES]; |
253 |
[vc release]; |
254 |
} |
255 |
|
256 |
#pragma mark - |
257 |
#pragma mark Helper methods |
258 |
|
259 |
- (NSString *)humanReadableSize:(unsigned long long)bytes { |
260 |
NSString *sizeUnit = @"bytes"; |
261 |
|
262 |
double sizeInBytes = bytes; |
263 |
if (bytes > 1023 && bytes < 1048576) { |
264 |
sizeInBytes = bytes / 1024.0; |
265 |
sizeUnit = @"Kb"; |
266 |
} |
267 |
else if (bytes > 1048575 && bytes < 1073741824) { |
268 |
sizeInBytes = bytes / 1048576.0; |
269 |
sizeUnit = @"Mb"; |
270 |
} |
271 |
else if (bytes > 1073741823) { |
272 |
sizeInBytes = bytes / 1073741824.0; |
273 |
sizeUnit = @"Gb"; |
274 |
} |
275 |
|
276 |
NSString *humanReadableString = [NSString stringWithFormat:@"%.1f %@", sizeInBytes, sizeUnit]; |
277 |
humanReadableString = [humanReadableString stringByReplacingOccurrencesOfString:@".0" withString:@""]; |
278 |
|
279 |
return humanReadableString; |
280 |
} |
281 |
|
282 |
- (void)createContainerWithName:(NSString *)containerName { |
283 |
[self hideToolbarInfoMessage]; |
284 |
[self showToolbarActivityMessage:@"Creating container..."]; |
285 |
Container *container = [[Container alloc] init]; |
286 |
container.name = containerName; |
287 |
[[self.account.manager createContainer:container] |
288 |
success:^(OpenStackRequest *request) { |
289 |
[self hideToolbarActivityMessage]; |
290 |
if (!account.sharingAccount) |
291 |
[self showToolbarInfoMessage:accountUsageInfo]; |
292 |
[self.tableView reloadData]; |
293 |
} |
294 |
failure:^(OpenStackRequest *request) { |
295 |
[self hideToolbarActivityMessage]; |
296 |
if (!account.sharingAccount) |
297 |
[self showToolbarInfoMessage:accountUsageInfo]; |
298 |
[self alert:@"There was a problem creating your container." request:request]; |
299 |
}]; |
300 |
[container release]; |
301 |
} |
302 |
|
303 |
|
304 |
#pragma mark - |
305 |
#pragma mark Memory management |
306 |
|
307 |
- (void)dealloc { |
308 |
[accountUsageInfo release]; |
309 |
[tableView release]; |
310 |
[account release]; |
311 |
[containerDetailViewController release]; |
312 |
[super dealloc]; |
313 |
} |
314 |
|
315 |
@end |