2 // EditAccountGroupsViewController.m
5 // Copyright 2011 GRNET S.A. All rights reserved.
7 // Redistribution and use in source and binary forms, with or
8 // without modification, are permitted provided that the following
11 // 1. Redistributions of source code must retain the above
12 // copyright notice, this list of conditions and the following
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.
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.
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.
38 #import "EditAccountGroupsViewController.h"
39 #import "UIViewController+Conveniences.h"
40 #import "AccountManager.h"
41 #import "OpenStackRequest.h"
43 #define kGroupDetails 0
47 @implementation EditAccountGroupsViewController
50 @synthesize groupName, groupUsers, removeGroupEnabled;
51 @synthesize groups,metadata;
66 #pragma mark - View lifecycle
75 [super viewDidUnload];
78 - (void)viewWillAppear:(BOOL)animated
80 [super viewWillAppear:animated];
83 - (void)viewDidAppear:(BOOL)animated
85 [super viewDidAppear:animated];
88 - (void)viewWillDisappear:(BOOL)animated
90 [super viewWillDisappear:animated];
93 - (void)viewDidDisappear:(BOOL)animated
95 [super viewDidDisappear:animated];
98 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
99 return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) || (toInterfaceOrientation == UIInterfaceOrientationPortrait);
102 #pragma mark - Table view data source
104 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
106 if (removeGroupEnabled)
112 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
114 if (section == kGroupDetails)
120 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
122 static NSString *CellIdentifier = @"Cell";
124 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
126 cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
129 cell.textLabel.text = @"";
130 cell.accessoryType = UITableViewCellAccessoryNone;
131 if (indexPath.section == kGroupDetails) {
132 UITextField *textField = nil;
133 for (id subView in cell.contentView.subviews) {
134 if ([subView isKindOfClass:[UITextField class]]) {
135 textField = (UITextField *)subView;
139 if (textField == nil) {
140 CGRect bounds = [cell.contentView bounds];
141 CGRect rect = CGRectInset(bounds, 20.0, 10.0);
142 textField = [[UITextField alloc] initWithFrame:rect];
143 [textField setFrame:rect];
146 [textField setClearButtonMode:UITextFieldViewModeWhileEditing];
147 [textField setBackgroundColor:[UIColor clearColor]];
148 [textField setOpaque:YES];
149 [textField setAutocorrectionType:UITextAutocorrectionTypeNo];
150 [textField setAutocapitalizationType:UITextAutocapitalizationTypeNone];
151 [textField setDelegate:self];
152 textField.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
154 if (indexPath.row == 0) {
155 textField.returnKeyType = UIReturnKeyNext;
156 textField.placeholder = @"Group name";
157 textField.text = self.groupName;
160 else if (indexPath.row == 1) {
161 textField.returnKeyType = UIReturnKeyDefault;
162 textField.placeholder = @"Group users";
163 textField.text = self.groupUsers;
166 cell.selectionStyle = UITableViewCellSelectionStyleNone;
167 [cell.contentView addSubview:textField];
169 else if (indexPath.section == kSave) {
170 cell.textLabel.text = @"Save";
172 else if (indexPath.section == kRemove) {
173 cell.textLabel.text = @"Remove";
180 #pragma mark - Table view delegate
182 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
184 NSString *activityMessage;
185 NSIndexPath *keyCellIndexPath;
186 NSIndexPath *valueCellIndexPath;
187 UITableViewCell *cell;
189 if (indexPath.section != kGroupDetails)
190 [self.view endEditing:YES];
192 if (indexPath.section == kSave) {
193 keyCellIndexPath = [NSIndexPath indexPathForRow:0 inSection:kGroupDetails];
194 cell = [self.tableView cellForRowAtIndexPath:keyCellIndexPath];
195 UITextField *textField = [[cell.contentView subviews] objectAtIndex:0];
196 NSString *newGroupName = textField.text;
198 if ([newGroupName length] == 0
199 || [[newGroupName stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length] == 0) {
200 [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
201 [self alert:@"Invalid input" message:@"Group name cannot be empty"];
205 valueCellIndexPath = [NSIndexPath indexPathForRow:1 inSection:kGroupDetails];
206 cell = [self.tableView cellForRowAtIndexPath:valueCellIndexPath];
207 textField = [[cell.contentView subviews] objectAtIndex:0];
208 NSString *newGroupUsers = textField.text;
210 activityMessage = @"Saving group";
212 activityIndicatorView = [[ActivityIndicatorView alloc] initWithFrame:[ActivityIndicatorView frameForText:activityMessage]text:activityMessage];
213 [activityIndicatorView addToView:self.view];
215 [groups removeObjectForKey:groupName];
216 [groups setObject:newGroupUsers forKey:newGroupName];
217 NSDictionary *accountInfo = [NSDictionary dictionaryWithObjectsAndKeys:groups, @"groups",
218 metadata, @"metadata",
221 [self.account.manager writeAccountMetadata:accountInfo];
222 successObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"writeAccountMetadataRequestSucceeded"
224 queue:[NSOperationQueue mainQueue]
225 usingBlock:^(NSNotification *notification)
227 [activityIndicatorView removeFromSuperviewAndRelease];
228 self.groupName = newGroupName;
229 self.groupUsers = newGroupUsers;
230 self.removeGroupEnabled = YES;
231 self.navigationItem.title = @"Edit Group";
232 [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
233 [[NSNotificationCenter defaultCenter] removeObserver:successObserver];
236 failureObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"writeAccountMetadataRequestFailed"
238 queue:[NSOperationQueue mainQueue]
239 usingBlock:^(NSNotification *notification)
241 [activityIndicatorView removeFromSuperviewAndRelease];
242 [groups removeObjectForKey:newGroupName];
243 [groups setObject:self.groupUsers forKey:self.groupName];
244 [self.tableView reloadData];
245 [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
246 [self alert:@"There was a problem saving the group information." request:[notification.userInfo objectForKey:@"request"]];
248 [[NSNotificationCenter defaultCenter] removeObserver:failureObserver];
250 } else if (indexPath.section == kRemove) {
251 activityMessage = @"Removing group";
252 activityIndicatorView = [[ActivityIndicatorView alloc] initWithFrame:[ActivityIndicatorView frameForText:activityMessage] text:activityMessage];
253 [activityIndicatorView addToView:self.view];
255 [groups removeObjectForKey:groupName];
256 NSDictionary *accountInfo = [NSDictionary dictionaryWithObjectsAndKeys:groups, @"groups",
257 metadata, @"metadata",
261 [self.account.manager writeAccountMetadata:accountInfo];
262 successObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"writeAccountMetadataRequestSucceeded"
264 queue:[NSOperationQueue mainQueue]
265 usingBlock:^(NSNotification *notification)
267 [activityIndicatorView removeFromSuperviewAndRelease];
268 self.groupName = @"";
269 self.groupUsers = @"";
270 [self.tableView reloadData];
271 [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
272 [[NSNotificationCenter defaultCenter] removeObserver:successObserver];
275 failureObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"writeAccountMetadataRequestFailed"
277 queue:[NSOperationQueue mainQueue]
278 usingBlock:^(NSNotification *notification)
280 [activityIndicatorView removeFromSuperviewAndRelease];
281 [groups setObject:groupUsers forKey:groupName];
282 [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
283 [self alert:@"There was a problem removing the group information." request:[notification.userInfo objectForKey:@"request"]];
285 [[NSNotificationCenter defaultCenter] removeObserver:failureObserver];
291 #pragma mark - Textfield delegate
293 //- (void)textFieldDidEndEditing:(UITextField *)textField {
294 // if ([textField tag] == 0) {
295 // if ([textField.text length] == 0
296 // || [[textField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length] == 0) {
297 // [self alert:@"Invalid input" message:@"Group name cannot be empty"];
302 - (BOOL)textFieldShouldReturn:(UITextField *)textField
305 if ([textField returnKeyType] == UIReturnKeyNext)
307 if ([textField.text length] == 0
308 || [[textField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length] == 0) {
309 [self alert:@"Invalid input" message:@"Group name cannot be empty"];
312 NSInteger nextTag = [textField tag] + 1;
313 UIView *nextTextField = [self.tableView viewWithTag:nextTag];
314 [nextTextField becomeFirstResponder];
318 [textField resignFirstResponder];