Clean and improve code
[pithos-ios] / Classes / AccountGroupsViewController.m
1 //
2 //  AccountGroupsViewController.m
3 //  pithos-ios
4 //
5 // Copyright 2011 GRNET S.A. All rights reserved.
6 //
7 // Redistribution and use in source and binary forms, with or
8 // without modification, are permitted provided that the following
9 // conditions are met:
10 // 
11 //   1. Redistributions of source code must retain the above
12 //      copyright notice, this list of conditions and the following
13 //      disclaimer.
14 // 
15 //   2. Redistributions in binary form must reproduce the above
16 //      copyright notice, this list of conditions and the following
17 //      disclaimer in the documentation and/or other materials
18 //      provided with the distribution.
19 // 
20 // THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
21 // OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
24 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
27 // USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28 // AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 // POSSIBILITY OF SUCH DAMAGE.
32 // 
33 // The views and conclusions contained in the software and
34 // documentation are those of the authors and should not be
35 // interpreted as representing official policies, either expressed
36 // or implied, of GRNET S.A.
37
38 #import "AccountGroupsViewController.h"
39 #import "OpenStackAccount.h"
40 #import "ActivityIndicatorView.h"
41 #import "AccountManager.h"
42 #import "OpenStackRequest.h"
43 #import "EditAccountGroupsViewController.h"
44 #import "UIViewController+Conveniences.h"
45 #import "NSString+Conveniences.h"
46 #import "APICallback.h"
47
48 @implementation AccountGroupsViewController
49
50 @synthesize account, groups;
51
52 #pragma mark - View lifecycle
53
54 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
55     return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) || (toInterfaceOrientation == UIInterfaceOrientationPortrait);
56 }
57
58 - (void)viewWillAppear:(BOOL)animated {
59     [super viewWillAppear:animated];
60     self.navigationItem.title = @"Groups";
61     groups = [[NSMutableDictionary alloc] init];
62     metadata = [[NSMutableDictionary alloc] init];
63     
64     NSString *activityMessage = @"Loading..";
65     activityIndicatorView = [[ActivityIndicatorView alloc] initWithFrame:[ActivityIndicatorView frameForText:activityMessage] text:activityMessage];
66     [activityIndicatorView addToView:self.view];
67     
68     [[self.account.manager getStorageAccountInfo]
69      success:^(OpenStackRequest *request) {
70          [activityIndicatorView removeFromSuperview];
71          for (NSString *key in request.responseHeaders) {
72              if ([key hasPrefix:@"X-Account-Group-"]) {
73                  NSString *groupUsers = [NSString decodeFromPercentEscape:[request.responseHeaders objectForKey:key]];
74                  NSString *groupName = [NSString decodeFromPercentEscape:[key substringFromIndex:16]];
75                  [groups setObject:groupUsers forKey:groupName];
76              }
77          }
78          
79          for (NSString *header in request.responseHeaders) {
80              if ([header hasPrefix:@"X-Account-Meta-"])  {
81                  NSString *metadataKey = [NSString decodeFromPercentEscape:[header substringFromIndex:15]];
82                  NSString *metadataValue = [NSString decodeFromPercentEscape:[request.responseHeaders objectForKey:header]];
83                  [metadata setObject:metadataValue forKey:metadataKey];
84              }
85          }
86          
87          [self.tableView reloadData];
88      }
89      failure:^(OpenStackRequest *request) {
90          [activityIndicatorView removeFromSuperview];
91          [self alert:@"Error" message:@"Failed to get account information"];
92      }];
93 }
94
95 #pragma mark - Memory management
96
97 - (void)dealloc {
98     [account release];
99     [groups release];
100     [metadata release];
101     [activityIndicatorView release];
102     [super dealloc];
103 }
104
105 #pragma mark - Internal
106
107 - (CGFloat)findLabelHeight:(NSString*)text font:(UIFont *)font {
108     CGSize textLabelSize;
109     if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
110         // 616, 678
111         textLabelSize = CGSizeMake(596.0, 9000.0f);
112     } else {
113         textLabelSize = CGSizeMake(280.0, 9000.0f);
114     }
115     CGSize stringSize = [text sizeWithFont:font constrainedToSize:textLabelSize lineBreakMode:UILineBreakModeCharacterWrap];
116     return stringSize.height;
117 }
118
119 #pragma mark - UITableViewDataSource
120
121 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
122     return [groups count] + 1;
123 }
124
125 - (CGFloat)tableView:(UITableView *)aTableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
126     CGFloat result;
127     
128     if ([groups count] > 0 && indexPath.row < [groups count]) {
129         NSString *groupName = [[groups allKeys] objectAtIndex:indexPath.row];
130         NSString *groupUsers = [groups objectForKey:groupName];
131         
132         result = 22.0 + [self findLabelHeight:[NSString stringWithFormat:@"%@", groupUsers] font:[UIFont systemFontOfSize:18.0]];
133     
134         return MAX(aTableView.rowHeight, result);
135     }
136     return aTableView.rowHeight;
137 }
138
139
140 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
141     static NSString *CellIdentifier = @"Cell";
142     
143     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
144     if (cell == nil) {
145         cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];
146     }
147     
148     cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
149     if (indexPath.row < [groups count]) {
150         NSString *groupName = [[groups allKeys] objectAtIndex:indexPath.row];
151         cell.textLabel.text = groupName;
152         cell.detailTextLabel.text = [groups objectForKey:groupName];
153         cell.detailTextLabel.numberOfLines = 0;
154         cell.detailTextLabel.lineBreakMode = UILineBreakModeCharacterWrap;
155     } else {
156         cell.textLabel.text = @"Add Group";
157         cell.detailTextLabel.text = @"";
158     }
159     
160     return cell;
161 }
162
163
164 #pragma mark - UITableViewDelegate
165
166 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
167     EditAccountGroupsViewController *vc = [[EditAccountGroupsViewController alloc] initWithNibName:@"EditAccountGroupsViewController" bundle:nil];
168     vc.account = self.account;
169     vc.metadata = metadata;
170     vc.groups = groups;
171     if (indexPath.row < [groups count]) {
172         NSString *groupName = [[groups allKeys] objectAtIndex:indexPath.row];
173         NSString *groupUsers = [groups objectForKey:groupName];
174         
175         vc.removeGroupEnabled = YES;
176         vc.groupName = groupName;
177         vc.groupUsers = groupUsers;
178         vc.navigationItem.title = @"Edit Group";
179     } else {
180         vc.removeGroupEnabled = NO;
181         vc.groupName = @"";
182         vc.groupUsers = @"";
183         vc.navigationItem.title = @"Add Group";
184     }
185     
186     [self.navigationController pushViewController:vc animated:YES];
187     [vc release];
188 }
189
190 @end