// // EditAccountGroupsViewController.m // pithos-ios // // Copyright 2011 GRNET S.A. All rights reserved. // // Redistribution and use in source and binary forms, with or // without modification, are permitted provided that the following // conditions are met: // // 1. Redistributions of source code must retain the above // copyright notice, this list of conditions and the following // disclaimer. // // 2. Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following // disclaimer in the documentation and/or other materials // provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS // OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF // USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED // AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. // // The views and conclusions contained in the software and // documentation are those of the authors and should not be // interpreted as representing official policies, either expressed // or implied, of GRNET S.A. #import "EditAccountGroupsViewController.h" #import "OpenStackAccount.h" #import "ActivityIndicatorView.h" #import "UIViewController+Conveniences.h" #import "AccountManager.h" #import "OpenStackRequest.h" #import "APICallback.h" #define kGroupDetails 0 #define kSave 1 #define kRemove 2 @implementation EditAccountGroupsViewController @synthesize account; @synthesize groupName, groupUsers, removeGroupEnabled; @synthesize groups,metadata; #pragma mark - View lifecycle - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation { return ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) || (toInterfaceOrientation == UIInterfaceOrientationPortrait); } #pragma mark - Memory management - (void)dealloc { [groupName release]; [groupUsers release]; [account release]; [metadata release]; [groups release]; [super dealloc]; } #pragma mark - Internal - (BOOL)userInputIsValid:(NSString *)input fieldName:(NSString *)fieldName { if (![input length] || ![[input stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length]) { [self alert:@"Invalid input" message:[NSString stringWithFormat:@"%@ field cannot be empty", fieldName]]; return NO; } NSCharacterSet *set = [NSCharacterSet characterSetWithCharactersInString:@"= "]; if ([input rangeOfCharacterFromSet:set].location != NSNotFound) { [self alert:@"Invalid input" message:[NSString stringWithFormat:@"%@ field cannot contain '=' or whitespace characters", fieldName]]; return NO; } return YES; } #pragma mark - UITableViewDataSource - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { if (removeGroupEnabled) return 3; else return 2; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { if (section == kGroupDetails) return 2; else return 1; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; } cell.textLabel.text = @""; cell.accessoryType = UITableViewCellAccessoryNone; if (indexPath.section == kGroupDetails) { UITextField *textField = nil; for (id subView in cell.contentView.subviews) { if ([subView isKindOfClass:[UITextField class]]) { textField = (UITextField *)subView; } } if (textField == nil) { CGRect bounds = [cell.contentView bounds]; CGRect rect = CGRectInset(bounds, 10.0, 10.0); textField = [[UITextField alloc] initWithFrame:rect]; [textField setFrame:rect]; } [textField setClearButtonMode:UITextFieldViewModeWhileEditing]; [textField setBackgroundColor:[UIColor clearColor]]; [textField setOpaque:YES]; [textField setAutocorrectionType:UITextAutocorrectionTypeNo]; [textField setAutocapitalizationType:UITextAutocapitalizationTypeNone]; [textField setDelegate:self]; textField.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; if (indexPath.row == 0) { textField.returnKeyType = UIReturnKeyNext; textField.placeholder = @"Group name"; textField.text = self.groupName; textField.tag = 0; } else if (indexPath.row == 1) { textField.returnKeyType = UIReturnKeyDefault; textField.placeholder = @"Group users"; textField.text = self.groupUsers; textField.tag = 1; } cell.selectionStyle = UITableViewCellSelectionStyleNone; [cell.contentView addSubview:textField]; } else if (indexPath.section == kSave) { cell.textLabel.text = @"Save"; } else if (indexPath.section == kRemove) { cell.textLabel.text = @"Remove"; } return cell; } #pragma mark - UITableViewDelegate - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { NSIndexPath *keyCellIndexPath; NSIndexPath *valueCellIndexPath; UITableViewCell *cell; if (indexPath.section != kGroupDetails) [self.view endEditing:YES]; if (indexPath.section == kSave) { keyCellIndexPath = [NSIndexPath indexPathForRow:0 inSection:kGroupDetails]; cell = [self.tableView cellForRowAtIndexPath:keyCellIndexPath]; UITextField *textField = [[cell.contentView subviews] objectAtIndex:0]; NSString *newGroupName = textField.text; if (![self userInputIsValid:newGroupName fieldName:@"Group name"]) { [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; return; } valueCellIndexPath = [NSIndexPath indexPathForRow:1 inSection:kGroupDetails]; cell = [self.tableView cellForRowAtIndexPath:valueCellIndexPath]; textField = [[cell.contentView subviews] objectAtIndex:0]; NSString *newGroupUsers = textField.text; if (![self userInputIsValid:newGroupUsers fieldName:@"Group users"]) { [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; return; } [groups removeObjectForKey:groupName]; [groups setObject:newGroupUsers forKey:newGroupName]; NSDictionary *accountInfo = [NSDictionary dictionaryWithObjectsAndKeys:groups, @"groups", metadata, @"metadata", nil ]; __block ActivityIndicatorView *activityIndicatorView = [ActivityIndicatorView activityIndicatorViewWithText:@"Saving group..." andAddToView:self.view]; [[self.account.manager writeAccountMetadata:accountInfo] success:^(OpenStackRequest *request) { [activityIndicatorView removeFromSuperview]; self.groupName = newGroupName; self.groupUsers = newGroupUsers; self.removeGroupEnabled = YES; self.navigationItem.title = @"Edit Group"; [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; [self.tableView reloadData]; } failure:^(OpenStackRequest *request) { [activityIndicatorView removeFromSuperview]; [groups removeObjectForKey:newGroupName]; [groups setObject:self.groupUsers forKey:self.groupName]; [self.tableView reloadData]; [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; [self alert:@"There was a problem saving the group information." request:request]; }]; } else if (indexPath.section == kRemove) { [groups removeObjectForKey:groupName]; NSDictionary *accountInfo = [NSDictionary dictionaryWithObjectsAndKeys:groups, @"groups", metadata, @"metadata", nil ]; __block ActivityIndicatorView *activityIndicatorView = [ActivityIndicatorView activityIndicatorViewWithText:@"Removing group..." andAddToView:self.view]; [[self.account.manager writeAccountMetadata:accountInfo] success:^(OpenStackRequest *request) { [activityIndicatorView removeFromSuperview]; self.groupName = @""; self.groupUsers = @""; self.removeGroupEnabled = NO; [self.tableView reloadData]; [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; } failure:^(OpenStackRequest *request) { [activityIndicatorView removeFromSuperview]; [groups setObject:groupUsers forKey:groupName]; [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; [self alert:@"There was a problem removing the group information." request:request]; }]; } } #pragma mark - UITextFieldDelegate - (BOOL)textFieldShouldReturn:(UITextField *)textField { if ([textField returnKeyType] == UIReturnKeyNext) { [self userInputIsValid:textField.text fieldName:@"Group name"]; NSInteger nextTag = [textField tag] + 1; UIView *nextTextField = [self.tableView viewWithTag:nextTag]; [nextTextField becomeFirstResponder]; } else { [self userInputIsValid:textField.text fieldName:@"Group users"]; [textField resignFirstResponder]; } return YES; } @end