2 // AccountHomeViewController.m
5 // Created by Mike Mayo on 10/7/10.
6 // The OpenStack project is provided under the Apache 2.0 license.
9 #import "AccountHomeViewController.h"
10 #import "OpenStackAccount.h"
12 #import "ContactInformationViewController.h"
13 #import "ServersViewController.h"
14 #import "NSObject+Conveniences.h"
15 #import "RootViewController.h"
16 #import "LimitsViewController.h"
18 #import "ContainersViewController.h"
19 #import "AccountManager.h"
20 #import "AccountSettingsViewController.h"
21 #import "RSSFeedsViewController.h"
22 #import "UIViewController+Conveniences.h"
24 #import "PasscodeViewController.h"
25 #import "OpenStackAppDelegate.h"
26 #import "LoadBalancersViewController.h"
27 #import "Reachability.h"
29 #import "AccountGroupsViewController.h"
30 #import "SharingAccountsViewController.h"
31 #import "PithosImageViewController.h"
33 #define kObjectStorage 0
37 @implementation AccountHomeViewController
39 @synthesize account, rootViewController, rootViewIndexPath, tableView;
42 #pragma mark View lifecycle
44 - (void)incrementRefreshCount {
46 //if (refreshCount == 2) {
47 self.account.hasBeenRefreshed = YES;
48 [self hideToolbarActivityMessage];
49 refreshButton.enabled = YES;
55 Reachability *reachability = [Reachability reachabilityForInternetConnection];
56 if ([reachability currentReachabilityStatus] == kNotReachable) {
57 self.account.hasBeenRefreshed = YES;
58 [self hideToolbarActivityMessage];
59 refreshButton.enabled = YES;
60 [self failOnBadConnection];
65 accountSettingsRow = 0;
66 accountMetadataRow = 1;
71 id getContainersObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"getContainersSucceeded" object:self.account
72 queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notification)
74 [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:storageRow inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
75 [self incrementRefreshCount];
77 id getContainersFailedObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"getContainersFailed" object:self.account
78 queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notification)
80 [self incrementRefreshCount];
82 id createContainerObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"createContainerSucceeded" object:self.account
83 queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notification)
85 [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:storageRow inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
87 id deleteContainerObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"deleteContainerSucceeded" object:self.account
88 queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notification)
90 [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:storageRow inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
93 observers = [[NSArray alloc] initWithObjects: getContainersObserver, getContainersFailedObserver, createContainerObserver, deleteContainerObserver, nil];
98 - (void)viewWillAppear:(BOOL)animated {
99 [super viewWillAppear:animated];
100 self.navigationItem.title = self.account.username;
103 account.sharingAccount = nil;
106 computeRow = (self.account.serversURL && [self.account.serversURL host]) ? totalRows++ : -1;
107 storageRow = (self.account.filesURL && [self.account.filesURL host]) ? totalRows++ : -1;
108 loadBalancingRow = [self.account loadBalancerURLs] ? totalRows++ : -1;
110 if (self.account.provider.rssFeeds && [self.account.provider.rssFeeds count] > 0) {
111 rssFeedsRow = totalRows++;
112 NSLog(@"rssfeedsrow: %d", rssFeedsRow);
116 if (self.account.provider.contactURLs && [self.account.provider.contactURLs count] > 0) {
117 contactRow = totalRows++;
121 /*if ([self.account.apiVersion isEqualToString:@"1.0"]) {
122 limitsRow = totalRows++;
127 [self.tableView reloadData];
129 if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
130 PithosImageViewController *vc = [[PithosImageViewController alloc] initWithNibName:@"PithosImageViewController" bundle:nil];
131 [self.navigationController presentPrimaryViewController:vc];
136 - (void)viewDidAppear:(BOOL)animated {
137 [super viewDidAppear:animated];
138 if (!self.account.hasBeenRefreshed) {
139 [self.account refreshCollections];
142 - (void)viewWillDisappear:(BOOL)animated {
143 // [rootViewController.tableView deselectRowAtIndexPath:rootViewIndexPath animated:YES];
144 [super viewWillDisappear:animated];
147 - (void)viewDidUnload {
148 for (id observer in observers) {
149 [[NSNotificationCenter defaultCenter] removeObserver:observer];
152 [super viewDidUnload];
154 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
155 return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) || (toInterfaceOrientation == UIInterfaceOrientationPortrait);
159 #pragma mark Table view data source
161 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
165 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
166 if (section == kObjectStorage)
172 - (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
174 static NSString *CellIdentifier = @"Cell";
176 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
178 cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
179 cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
182 cell.imageView.image = nil;
184 if (indexPath.section == kObjectStorage) {
185 if (indexPath.row == computeRow) {
186 cell.textLabel.text = [self.account.provider isRackspace] ? @"Cloud Servers" : @"Compute";
187 cell.imageView.image = [self.account.provider isRackspace] ? [UIImage imageNamed:kCloudServersIcon] : [UIImage imageNamed:@"openstack-icon.png"];
188 cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
189 } else if (indexPath.row == storageRow) {
190 cell.textLabel.text = [self.account.provider isRackspace] ? @"Cloud Files" : @"Object Storage";
191 cell.imageView.image = [self.account.provider isRackspace] ? [UIImage imageNamed:@"cloud-files-icon.png"] : [UIImage imageNamed:@"pithos-solo-smallest.png"];
192 } else if (indexPath.row == loadBalancingRow) {
193 cell.textLabel.text = @"Load Balancers";
194 cell.imageView.image = [UIImage imageNamed:@"load-balancers-icon.png"];
195 cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
196 } else if (indexPath.row == rssFeedsRow) {
197 cell.textLabel.text = @"System Status";
198 cell.imageView.image = [UIImage imageNamed:@"rss-feeds-icon.png"];
199 } else if (indexPath.row == contactRow) {
200 cell.textLabel.text = @"Fanatical Support"; // @"Contact Information";
201 cell.imageView.image = [UIImage imageNamed:@"contact-rackspace-icon.png"];
202 if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
203 cell.accessoryType = UITableViewCellAccessoryNone;
205 cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
207 } else if (indexPath.row == limitsRow) {
208 cell.textLabel.text = @"API Rate Limits";
209 cell.imageView.image = [UIImage imageNamed:@"api-rate-limits-icon.png"];
210 if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
211 cell.accessoryType = UITableViewCellAccessoryNone;
213 cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
216 } else if (indexPath.section == kShared) {
217 if (indexPath.row == mySharedRow) {
218 cell.textLabel.text = @" Shared By Me";
219 cell.imageView.image = [UIImage imageNamed:@"myShared.png"];
220 cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
221 } else if (indexPath.row == othersSharedRow) {
222 cell.textLabel.text = @"Shared To Me";
223 cell.imageView.image = [UIImage imageNamed:@"othersShared.png"];
224 cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
226 } else if (indexPath.section == kSettings) {
227 if (indexPath.row == accountSettingsRow) {
228 cell.textLabel.text = @"Account Token";
229 cell.imageView.image = [UIImage imageNamed:@"account-settings-icon.png"];
230 if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
231 cell.accessoryType = UITableViewCellAccessoryNone;
233 cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
235 } else if (indexPath.row == accountMetadataRow) {
236 cell.textLabel.text = @"Account Metadata";
237 cell.imageView.image = [UIImage imageNamed:@"account-settings-icon.png"];
238 if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
239 cell.accessoryType = UITableViewCellAccessoryNone;
241 cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
250 #pragma mark Table view delegate
252 - (void)tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
253 [super tableView:aTableView didSelectRowAtIndexPath:indexPath];
255 OpenStackAppDelegate *app = [[UIApplication sharedApplication] delegate];
256 BOOL shouldHidePopover = NO;
258 if (indexPath.section == kObjectStorage) {
259 if (indexPath.row == computeRow) {
260 ServersViewController *vc = [[ServersViewController alloc] initWithNibName:@"ServersViewController" bundle:nil];
261 vc.account = account;
262 vc.accountHomeViewController = self;
263 vc.comingFromAccountHome = YES;
264 [self.navigationController pushViewController:vc animated:YES];
266 } else if (indexPath.row == storageRow) {
267 ContainersViewController *vc = [[ContainersViewController alloc] initWithNibName:@"ContainersViewController" bundle:nil];
269 vc.account = account;
270 vc.accountHomeViewController = self;
271 [self.navigationController pushViewController:vc animated:YES];
272 [vc refreshButtonPressed:nil];
274 } else if (indexPath.row == loadBalancingRow) {
275 LoadBalancersViewController *vc = [[LoadBalancersViewController alloc] initWithNibName:@"LoadBalancersViewController" bundle:nil];
276 vc.account = account;
277 [self.navigationController pushViewController:vc animated:YES];
279 } else if (indexPath.row == rssFeedsRow) {
280 RSSFeedsViewController *vc = [[RSSFeedsViewController alloc] initWithNibName:@"RSSFeedsViewController" bundle:nil];
281 vc.account = account;
282 vc.comingFromAccountHome = YES;
283 [self.navigationController pushViewController:vc animated:YES];
285 } else if (indexPath.row == contactRow) {
286 NSString *nibName = @"ContactInformationViewController";
287 if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
288 nibName = @"ContactInformationViewController-iPad";
290 ContactInformationViewController *vc = [[ContactInformationViewController alloc] initWithNibName:nibName bundle:nil];
291 vc.provider = account.provider;
292 if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
293 [self.navigationController presentPrimaryViewController:vc];
294 shouldHidePopover = YES;
296 [self.navigationController pushViewController:vc animated:YES];
299 } else if (indexPath.row == limitsRow) {
300 LimitsViewController *vc = [[LimitsViewController alloc] initWithNibName:@"LimitsViewController" bundle:nil];
301 vc.account = account;
302 if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
303 [self.navigationController presentPrimaryViewController:vc];
304 shouldHidePopover = YES;
306 [self.navigationController pushViewController:vc animated:YES];
310 } else if (indexPath.section == kShared) {
311 if (indexPath.row == mySharedRow) {
312 ContainersViewController *vc = [[ContainersViewController alloc] initWithNibName:@"ContainersViewController" bundle:nil];
313 account.shared = YES;
314 vc.account = account;
315 vc.accountHomeViewController = self;
316 [self.navigationController pushViewController:vc animated:YES];
317 [vc refreshButtonPressed:nil];
319 } else if (indexPath.row == othersSharedRow){
320 SharingAccountsViewController *vc = [[SharingAccountsViewController alloc] initWithNibName:@"SharingAccountsViewController" bundle:nil];
321 vc.account = account;
322 vc.accountHomeViewController = self;
323 [self.navigationController pushViewController:vc animated:YES];
326 } else if (indexPath.section == kSettings) {
327 if (indexPath.row == accountSettingsRow) {
328 AccountSettingsViewController *vc = [[AccountSettingsViewController alloc] initWithNibName:@"AccountSettingsViewController" bundle:nil];
329 vc.account = account;
330 if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
331 [self.navigationController presentPrimaryViewController:vc];
332 shouldHidePopover = YES;
334 [self.navigationController pushViewController:vc animated:YES];
337 } else if (indexPath.row == accountMetadataRow) {
338 AccountGroupsViewController *vc = [[AccountGroupsViewController alloc] initWithNibName:@"AccountGroupsViewController" bundle:nil];
339 vc.account = self.account;
340 if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
341 [self.navigationController presentPrimaryViewController:vc];
342 shouldHidePopover = YES;
344 [self.navigationController pushViewController:vc animated:YES];
350 if (shouldHidePopover) {
351 if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad && app.rootViewController.popoverController != nil) {
352 [app.rootViewController.popoverController dismissPopoverAnimated:YES];
358 #pragma mark Button Handlers
360 - (void)refreshButtonPressed:(id)sender {
362 [self.account refreshCollections];
366 #pragma mark Memory management
370 [rootViewController release];