UI changes.
[pithos-ios] / Classes / EditPermissionsViewController.m
1 //
2 //  EditPermissionsViewController.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 "EditPermissionsViewController.h"
39 #import "AccountManager.h"
40 #import "UIViewController+Conveniences.h"
41
42 #define kUser 0
43 #define kPermissions 1
44 #define kRemovePermissions 2
45
46 @implementation EditPermissionsViewController
47
48 @synthesize account, container, object;
49 @synthesize user, readPermissionSelected, writePermissionSelected, permissions;
50 @synthesize oldPermissionsString;
51 @synthesize newPermissionsEntry;
52
53
54 - (void)dealloc
55 {
56     [super dealloc];
57 }
58
59 - (void)didReceiveMemoryWarning
60 {
61     // Releases the view if it doesn't have a superview.
62     [super didReceiveMemoryWarning];
63     
64     // Release any cached data, images, etc that aren't in use.
65 }
66
67 #pragma mark - View lifecycle
68
69 - (void)viewDidLoad
70 {
71     [super viewDidLoad];
72
73 }
74
75 - (void)viewDidUnload
76 {
77     [super viewDidUnload];
78 }
79
80 - (void)viewWillAppear:(BOOL)animated
81 {
82     [super viewWillAppear:animated];
83 }
84
85 - (void)viewDidAppear:(BOOL)animated
86 {
87     [super viewDidAppear:animated];
88 }
89
90 - (void)viewWillDisappear:(BOOL)animated
91 {
92     [super viewWillDisappear:animated];
93 }
94
95 - (void)viewDidDisappear:(BOOL)animated
96 {
97     [super viewDidDisappear:animated];
98 }
99
100 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
101     return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) || (toInterfaceOrientation == UIInterfaceOrientationPortrait);
102 }
103
104 #pragma mark - Table view data source
105
106 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
107 {
108     if (newPermissionsEntry)
109         return 2;
110     else 
111         return 3;
112 }
113
114 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
115 {
116     if (section == kPermissions)
117         return 2;
118     else
119         return 1;
120 }
121
122 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
123 {
124     static NSString *CellIdentifier = @"Cell";
125     
126     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
127     if (cell == nil) {
128         cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
129     }
130
131     if (indexPath.section == kUser) {
132         if (newPermissionsEntry) {
133             CGRect bounds = [cell.contentView bounds];
134             CGRect rect = CGRectInset(bounds, 20.0, 10.0);                        
135             UITextField *textField = [[UITextField alloc] initWithFrame:rect];
136             [textField setFrame:rect];
137             [textField setClearButtonMode:UITextFieldViewModeWhileEditing];
138             [textField setBackgroundColor:[UIColor clearColor]];
139             [textField setOpaque:YES];
140             [textField setAutocorrectionType:UITextAutocorrectionTypeNo];
141             [textField setAutocapitalizationType:UITextAutocapitalizationTypeNone];
142             [textField setDelegate:self];
143             textField.placeholder = @"User";
144             
145             cell.selectionStyle = UITableViewCellSelectionStyleNone;
146             [cell.contentView addSubview:textField];
147         }
148         else {
149             for (id subView in cell.contentView.subviews) {
150                 if ([subView isKindOfClass:[UITextField class]]) {
151                     [subView removeFromSuperview];
152                 }
153             }
154             
155             cell.accessoryType = UITableViewCellAccessoryNone;
156             cell.selectionStyle = UITableViewCellSelectionStyleNone;
157         }
158         cell.textLabel.text = self.user;
159         cell.selectionStyle = UITableViewCellSelectionStyleNone;
160     }
161     else if (indexPath.section == kPermissions) {
162         cell.selectionStyle = UITableViewCellSelectionStyleNone;
163         if (indexPath.row == 0) {
164             cell.textLabel.text = @"Read";
165             if (readPermissionSelected)
166                 cell.accessoryType = UITableViewCellAccessoryCheckmark;
167             else
168                 cell.accessoryType = UITableViewCellAccessoryNone;
169         }
170         else {
171             cell.textLabel.text = @"Write";
172             if (writePermissionSelected)
173                 cell.accessoryType = UITableViewCellAccessoryCheckmark;
174             else
175                 cell.accessoryType = UITableViewCellAccessoryNone;
176         }
177     } 
178     else if (indexPath.section == kRemovePermissions) {
179         cell.textLabel.text = @"Remove";
180         cell.accessoryType = UITableViewCellAccessoryNone;
181     }
182     
183     return cell;
184 }
185
186 #pragma mark - Table view delegate
187
188 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
189 {    
190     
191     
192     NSString *newUserName;
193     if (newPermissionsEntry) {
194         NSIndexPath *userCellIndexPath = [NSIndexPath indexPathForRow:0 inSection:kUser];
195         UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:userCellIndexPath];
196         UITextField *textField = [[cell.contentView subviews] objectAtIndex:0];
197         newUserName = textField.text;
198     
199         if (![self userInputIsValid:newUserName])
200             return; 
201     }
202
203     if (indexPath.section == kPermissions) {
204         if (indexPath.row == 0) {
205             if (!readPermissionSelected) {
206                 readPermissionSelected = YES;
207                 [self.permissions setObject:@"read" forKey:newUserName];
208                 if (writePermissionSelected)
209                     writePermissionSelected = FALSE;
210                 permissionsChanged = YES;
211             }
212             else 
213                 permissionsChanged = NO;
214         }
215         else if (indexPath.row == 1) {
216             if (!writePermissionSelected) {
217                 writePermissionSelected = YES;
218                 [self.permissions setObject:@"write" forKey:newUserName];
219                 if (readPermissionSelected)
220                     readPermissionSelected = FALSE;
221                 permissionsChanged = YES;
222             }
223             else
224                 permissionsChanged = NO;
225         }
226         
227         if (permissionsChanged) {
228             [self.tableView reloadData];
229             NSString *activityMessage = @"Applying permissions...";
230             activityIndicatorView = [[ActivityIndicatorView alloc] initWithFrame:[ActivityIndicatorView frameForText:activityMessage] text:activityMessage];
231             [activityIndicatorView addToView:self.view];
232             self.oldPermissionsString = object.sharing;
233             object.sharing = [self buildPermissionsString];
234             [self.account.manager writeObjectMetadata:container object:object];
235             successObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"writeObjectMetadataSucceeded"
236                                                                                 object:object
237                                                                                  queue:[NSOperationQueue mainQueue]
238                                                                             usingBlock:^(NSNotification *notification)
239                                {
240                                    if (newPermissionsEntry) {
241                                        self.user = newUserName;
242                                        newPermissionsEntry = FALSE;
243                                        [self.tableView reloadData];
244                                    }
245                                    [activityIndicatorView removeFromSuperviewAndRelease];
246                                    [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
247                                    [[NSNotificationCenter defaultCenter] removeObserver:successObserver];
248                                }];
249             failureObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"writeObjectMetadataFailed" 
250                                                                                 object:object 
251                                                                                  queue:[NSOperationQueue mainQueue] 
252                                                                             usingBlock:^(NSNotification *notification)
253                                {
254                                    object.sharing = self.oldPermissionsString;
255                                    if (!newPermissionsEntry) {
256                                        readPermissionSelected = !readPermissionSelected;
257                                        writePermissionSelected = !writePermissionSelected;
258                                    }
259                                    else {
260                                        self.user = @"";
261                                        readPermissionSelected = FALSE;
262                                        writePermissionSelected = FALSE;
263                                    }
264                                    if (readPermissionSelected)
265                                        [self.permissions setObject:@"read" forKey:user];
266                                    else if (writePermissionSelected) 
267                                        [self.permissions setObject:@"write" forKey:user];
268                                
269                                    [activityIndicatorView removeFromSuperviewAndRelease];
270                                    [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
271                                    [self.tableView reloadData];
272                                    [self alert:@"There was a problem applying the permissions." request:[notification.userInfo objectForKey:@"request"]];
273                                    [[NSNotificationCenter defaultCenter] removeObserver:failureObserver];
274                                }];
275         }
276     } 
277     else if (indexPath.section == kRemovePermissions) {
278         NSString *activityMessage = @"Removing permissions...";            
279         activityIndicatorView = [[ActivityIndicatorView alloc] initWithFrame:[ActivityIndicatorView frameForText:activityMessage] text:activityMessage];
280         [activityIndicatorView addToView:self.view];
281         
282         [permissions removeObjectForKey:user];
283         self.oldPermissionsString = object.sharing;
284         object.sharing = [self buildPermissionsString];
285         [self.account.manager writeObjectMetadata:container object:object];
286         successObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"writeObjectMetadataSucceeded"
287                                                                             object:object
288                                                                              queue:[NSOperationQueue mainQueue]
289                                                                         usingBlock:^(NSNotification *notification)
290                            {
291                                self.user = @"";
292                                self.readPermissionSelected = FALSE;
293                                self.writePermissionSelected = FALSE;
294                                [self.tableView reloadData];
295                                [activityIndicatorView removeFromSuperviewAndRelease];
296                                [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
297                                [[NSNotificationCenter defaultCenter] removeObserver:successObserver];
298                            }];
299
300         
301         failureObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"writeObjectMetadataFailed" 
302                                                                             object:object 
303                                                                              queue:[NSOperationQueue mainQueue] 
304                                                                         usingBlock:^(NSNotification *notification)
305                            {
306                                object.sharing = self.oldPermissionsString;
307                                if (readPermissionSelected)
308                                    [self.permissions setObject:@"read" forKey:user];
309                                else if (writePermissionSelected) 
310                                    [self.permissions setObject:@"write" forKey:user];
311
312                                [activityIndicatorView removeFromSuperviewAndRelease];
313                                [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
314                                [self.tableView reloadData];
315                                [self alert:@"There was a problem removing the permissions." request:[notification.userInfo objectForKey:@"request"]];
316                                [[NSNotificationCenter defaultCenter] removeObserver:failureObserver];
317                            }];
318     }
319 }
320
321 #pragma mark - Textfield delegate
322
323 - (void)textFieldDidEndEditing:(UITextField *)textField
324 {
325     [self userInputIsValid:textField.text];
326 }
327
328
329 - (BOOL)textFieldShouldReturn:(UITextField *)textField
330 {
331     [textField resignFirstResponder];
332     return YES;
333 }
334
335 #pragma mark - helper methods
336
337 - (NSString *)buildPermissionsString
338 {
339     NSString *readPermissionsString = @"";
340     NSString *writePermissionsString = @"";
341     for (NSString *aUser in [permissions allKeys]) {
342         if ([[permissions objectForKey:aUser] isEqual:@"read"]) {
343             if ([readPermissionsString length] == 0)
344                 readPermissionsString = [NSString stringWithFormat:@"read=%@", aUser];
345             else
346                 readPermissionsString = [NSString stringWithFormat:@"%@,%@", readPermissionsString ,aUser];
347         }
348         else if ([[permissions objectForKey:aUser] isEqual:@"write"]) {
349             if ([writePermissionsString length] == 0)
350                 writePermissionsString = [NSString stringWithFormat:@"write=%@", aUser];
351             else
352                 writePermissionsString = [NSString stringWithFormat:@"%@,%@", writePermissionsString, aUser];
353         }
354     }
355     
356     if ([writePermissionsString length] == 0)
357         return readPermissionsString;
358     else if ([readPermissionsString length] == 0)
359         return writePermissionsString;
360     else return [NSString stringWithFormat:@"%@;%@", readPermissionsString, writePermissionsString];
361 }
362
363 - (BOOL)userInputIsValid:(NSString *)input {
364     if ([input length] == 0
365         || [[input stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length] == 0
366         ) {
367         [self alert:@"Invalid input" message:@"User name field cannot be empty"];
368         return NO;
369     }
370     else {
371         NSCharacterSet *set = [NSCharacterSet characterSetWithCharactersInString:@"=,;"];
372         if ([input rangeOfCharacterFromSet:set].location != NSNotFound) {
373             [self alert:@"Invalid input" message:@"User name cannot contain '=', ',' or ';'"];
374             return NO;
375         }
376         else {
377             return YES;
378         }
379     }
380     
381     return YES;
382 }
383
384 @end