Create application/directory for subdir, if metadata or permissions are applied.
[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 "AccountManager.h"
40 #import "OpenStackRequest.h"
41 #import "EditAccountGroupsViewController.h"
42 #import "UIViewController+Conveniences.h"
43 #import "NSString+Conveniences.h"
44
45
46 @implementation AccountGroupsViewController
47
48 @synthesize account, groups;
49
50
51 - (void)dealloc
52 {
53     [account release];
54     [groups release];
55     [metadata release];
56     [super dealloc];
57 }
58
59
60 #pragma mark - View lifecycle
61
62 - (void)viewDidLoad
63 {
64     [super viewDidLoad];
65     self.navigationItem.title = @"Groups";
66     groups = [[NSMutableDictionary alloc] init];
67     metadata = [[NSMutableDictionary alloc] init];
68     
69     NSString *activityMessage = @"Loading..";
70     activityIndicatorView = [[ActivityIndicatorView alloc] initWithFrame:[ActivityIndicatorView frameForText:activityMessage] text:activityMessage];
71     [activityIndicatorView addToView:self.view];
72     
73     [self.account.manager getStorageAccountInfo];
74     successObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"getStorageAccountInfoSucceeded" 
75                                                                         object:account
76                                                                          queue:[NSOperationQueue mainQueue]
77                                                                     usingBlock:^(NSNotification *notification)
78     {
79         [activityIndicatorView removeFromSuperviewAndRelease];
80         OpenStackRequest *request = [notification.userInfo objectForKey:@"request"];
81         for (NSString *key in request.responseHeaders) {
82             if ([key hasPrefix:@"X-Account-Group-"]) {
83                 NSString *groupUsers = [NSString decodeFromPercentEscape:[request.responseHeaders objectForKey:key]];
84                 NSString *groupName = [NSString decodeFromPercentEscape:[key substringFromIndex:16]];
85                 [groups setObject:groupUsers forKey:groupName];
86             }
87         }
88         
89         for (NSString *header in request.responseHeaders) {
90             if ([header hasPrefix:@"X-Account-Meta-"])  {
91                 NSString *metadataKey = [NSString decodeFromPercentEscape:[header substringFromIndex:15]];
92                 NSString *metadataValue = [NSString decodeFromPercentEscape:[request.responseHeaders objectForKey:header]];
93                 [metadata setObject:metadataValue forKey:metadataKey];
94             }
95         }
96         
97         [self.tableView reloadData];
98         [[NSNotificationCenter defaultCenter] removeObserver:successObserver];
99     }];
100     
101     failureObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"getStorageAccountInfoFailed"
102                                                                         object:account
103                                                                          queue:[NSOperationQueue mainQueue]
104                                                                     usingBlock:^(NSNotification *notification)
105                        {
106                            [activityIndicatorView removeFromSuperviewAndRelease];
107                            [self alert:@"Error" message:@"Failed to get account information"];
108                            [[NSNotificationCenter defaultCenter] removeObserver:successObserver];
109                         }];
110 }
111
112 - (void)viewDidUnload
113 {
114     [super viewDidUnload];
115     // Release any retained subviews of the main view.
116     // e.g. self.myOutlet = nil;
117 }
118
119 - (void)viewWillAppear:(BOOL)animated
120 {
121     [super viewWillAppear:animated];
122     [self.tableView reloadData];
123 }
124
125 - (void)viewDidAppear:(BOOL)animated
126 {
127     [super viewDidAppear:animated];
128 }
129
130 - (void)viewWillDisappear:(BOOL)animated
131 {
132     [super viewWillDisappear:animated];
133 }
134
135 - (void)viewDidDisappear:(BOOL)animated
136 {
137     [super viewDidDisappear:animated];
138 }
139
140 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
141     return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) || (toInterfaceOrientation == UIInterfaceOrientationPortrait);
142 }
143
144 #pragma mark - Table view data source
145
146 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
147 {
148     return 1;
149 }
150
151 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
152 {
153     return [groups count] + 1;
154 }
155
156 - (CGFloat)findLabelHeight:(NSString*)text font:(UIFont *)font {
157     CGSize textLabelSize;    
158     if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
159         // 616, 678
160         textLabelSize = CGSizeMake(596.0, 9000.0f);
161     } else {
162         textLabelSize = CGSizeMake(280.0, 9000.0f);
163     }
164     CGSize stringSize = [text sizeWithFont:font constrainedToSize:textLabelSize lineBreakMode:UILineBreakModeCharacterWrap];
165     return stringSize.height;
166 }
167
168 - (CGFloat)tableView:(UITableView *)aTableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
169     CGFloat result = aTableView.rowHeight;
170     
171     if ([groups count] > 0 && indexPath.row < [groups count]) {
172         NSString *groupName = [[groups allKeys] objectAtIndex:indexPath.row];
173         NSString *groupUsers = [groups objectForKey:groupName];
174         
175         result = 22.0 + [self findLabelHeight:[NSString stringWithFormat:@"%@", groupUsers] font:[UIFont systemFontOfSize:18.0]];
176     
177         return MAX(aTableView.rowHeight, result);
178     }
179     return aTableView.rowHeight;
180 }
181
182
183 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
184 {
185     static NSString *CellIdentifier = @"Cell";
186     
187     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
188     if (cell == nil) {
189         cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];
190     }
191     
192     cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
193     if (indexPath.row < [groups count]) {
194         NSString *groupName = [[groups allKeys] objectAtIndex:indexPath.row];
195         cell.textLabel.text = groupName;
196         cell.detailTextLabel.text = [groups objectForKey:groupName];
197         cell.detailTextLabel.numberOfLines = 0;
198         cell.detailTextLabel.lineBreakMode = UILineBreakModeCharacterWrap;
199     }
200     else {
201         cell.textLabel.text = @"Add Group";
202         cell.detailTextLabel.text = @"";
203     }
204     
205     return cell;
206 }
207
208
209 #pragma mark - Table view delegate
210
211 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
212 {
213     EditAccountGroupsViewController *vc = [[EditAccountGroupsViewController alloc] initWithNibName:@"EditAccountGroupsViewController" bundle:nil];
214     
215     vc.account = self.account;
216     vc.metadata = metadata;
217     vc.groups = groups;
218     if (indexPath.row < [groups count]) {        
219         NSString *groupName = [[groups allKeys] objectAtIndex:indexPath.row];
220         NSString *groupUsers = [groups objectForKey:groupName];
221         
222         vc.removeGroupEnabled = YES;
223         vc.groupName = groupName;
224         vc.groupUsers = groupUsers;
225         vc.navigationItem.title = @"Edit Group";
226     }
227     else {
228         vc.removeGroupEnabled = NO;
229         vc.groupName = @"";
230         vc.groupUsers = @"";
231         vc.navigationItem.title = @"Add Group";
232     }
233     
234     [self.navigationController pushViewController:vc animated:YES];
235     [vc release];
236 }
237
238
239 @end