Added public object functionality.
[pithos-ios] / Classes / EditMetadataViewController.m
1 //
2 //  EditMetadataViewController.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 "EditMetadataViewController.h"
39 #import "AccountManager.h"
40 #import "UIViewController+Conveniences.h"
41
42
43
44 @implementation EditMetadataViewController
45
46
47 @synthesize container, account, object;
48
49 @synthesize metadataKey;
50 @synthesize metadataValue;
51 @synthesize deleteEnabled;
52
53 #define kMetadata 0 
54 #define kSaveMedata 1
55 #define kDeleteMetadata 2
56
57
58 - (void)dealloc
59 {
60     [account release];
61     [container release];
62     [object release];
63     [metadataKey release];
64     [metadataValue release];
65     [super dealloc];
66 }
67
68 - (void)didReceiveMemoryWarning
69 {
70     // Releases the view if it doesn't have a superview.
71     [super didReceiveMemoryWarning];
72     
73     // Release any cached data, images, etc that aren't in use.
74 }
75
76 #pragma mark - View lifecycle
77
78 - (void)viewDidLoad
79 {
80     [super viewDidLoad];
81 }
82
83 - (void)viewDidUnload
84 {
85     [super viewDidUnload];
86 }
87
88 - (void)viewWillAppear:(BOOL)animated
89 {    
90     [super viewWillAppear:animated];
91 }
92
93 - (void)viewDidAppear:(BOOL)animated
94 {
95     [super viewDidAppear:animated];
96 }
97
98 - (void)viewWillDisappear:(BOOL)animated
99 {
100     [super viewWillDisappear:animated];
101 }
102
103 - (void)viewDidDisappear:(BOOL)animated
104 {
105     [super viewDidDisappear:animated];
106 }
107
108 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
109     return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) || (toInterfaceOrientation == UIInterfaceOrientationPortrait);
110 }
111
112 #pragma mark - Table view data source
113
114 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
115 {
116     return (deleteEnabled)? 3:2;
117 }
118
119 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
120 {
121     if (section == kMetadata)
122         return 2;
123     else
124         return 1;
125 }
126
127 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
128 {
129     static NSString *CellIdentifier = @"Cell";
130     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
131     if (cell == nil) {
132         cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
133     }
134     CGRect bounds = [cell.contentView bounds];
135     CGRect rect = CGRectInset(bounds, 20.0, 10.0);                        
136     UITextField *textField = [[UITextField alloc] initWithFrame:rect];
137     [textField setFrame:rect];
138     [textField setClearButtonMode:UITextFieldViewModeWhileEditing];
139     [textField setBackgroundColor:[UIColor whiteColor]];
140     [textField setOpaque:YES];
141     [textField setAutocorrectionType:UITextAutocorrectionTypeNo];
142     [textField setAutocapitalizationType:UITextAutocapitalizationTypeNone];
143     [textField setDelegate:self];
144             
145     if (indexPath.section == kMetadata) {
146         if (indexPath.row == 0) {
147             [textField setReturnKeyType:UIReturnKeyNext];
148             textField.placeholder = @"Key";
149             textField.text = metadataKey;
150             textField.tag = 0;
151         }
152         else if (indexPath.row == 1) {
153             textField.placeholder = @"Value";
154             textField.text = metadataValue;
155             textField.tag = 1;
156         }
157             
158         cell.selectionStyle = UITableViewCellSelectionStyleNone;
159         [cell.contentView addSubview:textField];
160     }
161     else if (indexPath.section == kSaveMedata) 
162         cell.textLabel.text = @"Save";
163     else if (indexPath.section == kDeleteMetadata)
164         cell.textLabel.text = @"Delete";
165     
166     return cell;
167 }
168
169
170 #pragma mark - Table view delegate
171
172 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
173 {
174     NSString *activityMessage;
175     NSIndexPath *keyCellIndexPath;
176     NSIndexPath *valueCellIndexPath;
177     UITableViewCell *cell;
178     switch (indexPath.section) {
179         case kSaveMedata:
180             keyCellIndexPath = [NSIndexPath indexPathForRow:0 inSection:kMetadata];
181             cell = [self.tableView cellForRowAtIndexPath:keyCellIndexPath];
182             UITextField *textField = [[cell.contentView subviews] objectAtIndex:0];
183             NSString *newMetadataKey = textField.text;
184         
185             if ([newMetadataKey length] == 0
186                 || [[newMetadataKey stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length] == 0) {
187                 [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
188                 [self alert:@"Invalid input" message:@"Metadata key cannot be empty"];
189                 return;
190             }
191             
192             valueCellIndexPath = [NSIndexPath indexPathForRow:1 inSection:kMetadata];
193             cell = [self.tableView cellForRowAtIndexPath:valueCellIndexPath];
194             textField = [[cell.contentView subviews] objectAtIndex:0];
195             NSString *newMetadataValue = textField.text;
196             
197             activityMessage = @"Saving metadata";
198             
199             activityIndicatorView = [[ActivityIndicatorView alloc] initWithFrame:[ActivityIndicatorView frameForText:activityMessage] text:activityMessage];
200             [activityIndicatorView addToView:self.view];
201
202             [object.metadata removeObjectForKey:metadataKey];
203             [object.metadata setObject:newMetadataValue forKey:newMetadataKey];
204             [self.account.manager writeObjectMetadata:container object:object];
205             successObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"writeObjectMetadataSucceeded"
206                                                                                 object:object
207                                                                                  queue:[NSOperationQueue mainQueue]
208                                                                             usingBlock:^(NSNotification *notification)
209                                {
210                                    self.metadataKey = newMetadataKey;
211                                    self.metadataValue = newMetadataValue;
212                                    
213                                    [activityIndicatorView removeFromSuperviewAndRelease];
214                                    [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
215                                    [[NSNotificationCenter defaultCenter] removeObserver:successObserver];
216                                }];
217             
218             failureObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"writeObjectMetadataFailed" 
219                                                                                 object:object 
220                                                                                  queue:[NSOperationQueue mainQueue] 
221                                                                             usingBlock:^(NSNotification *notification)
222                                {
223                                    [object.metadata removeObjectForKey:newMetadataKey];
224                                    [object.metadata setObject:metadataValue forKey:metadataKey];
225                                    [activityIndicatorView removeFromSuperviewAndRelease];
226                                    [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
227                                    [self alert:@"There was a problem saving the metadata." request:[notification.userInfo objectForKey:@"request"]];
228                                    
229                                    [[NSNotificationCenter defaultCenter] removeObserver:failureObserver];
230                                }];
231             
232             break;
233         case kDeleteMetadata:
234             activityMessage = @"Deleting metadata";
235             activityIndicatorView = [[ActivityIndicatorView alloc] initWithFrame:[ActivityIndicatorView frameForText:activityMessage] text:activityMessage];
236             [activityIndicatorView addToView:self.view];
237
238             [object.metadata removeObjectForKey:metadataKey];
239             [self.account.manager writeObjectMetadata:container object:object];
240             successObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"writeObjectMetadataSucceeded"
241                                                                                 object:object
242                                                                                  queue:[NSOperationQueue mainQueue]
243                                                                             usingBlock:^(NSNotification *notification)
244                                {
245                                    [activityIndicatorView removeFromSuperviewAndRelease];
246                                    [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
247                                    self.metadataKey = @"";
248                                    self.metadataValue = @"";
249
250                                    [self.tableView reloadData];
251                                    [[NSNotificationCenter defaultCenter] removeObserver:successObserver];
252                                }];
253             
254             failureObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"writeObjectMetadataFailed" 
255                                                                                 object:object 
256                                                                                  queue:[NSOperationQueue mainQueue] 
257                                                                             usingBlock:^(NSNotification *notification)
258                                {
259                                    [object.metadata setObject:metadataValue forKey:metadataKey];
260                                    [activityIndicatorView removeFromSuperviewAndRelease];
261                                    [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
262                                    [self alert:@"There was a problem saving the metadata." request:[notification.userInfo objectForKey:@"request"]];
263                                    
264                                    [[NSNotificationCenter defaultCenter] removeObserver:failureObserver];
265                                }];
266
267             break;
268     }
269 }
270
271 #pragma mark - Textfield delegate
272
273 - (void)textFieldDidEndEditing:(UITextField *)textField
274 {
275     if ([textField tag] == 0) {
276         if ([textField.text length] == 0
277             || [[textField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length] == 0) {
278             [self alert:@"Invalid input" message:@"Metadata key cannot be empty"];
279         }
280     }
281 }
282
283
284
285 - (BOOL)textFieldShouldReturn:(UITextField *)textField
286 {
287     
288     if ([textField returnKeyType] == UIReturnKeyNext)
289     {
290         NSInteger nextTag = [textField tag] + 1;
291         UIView *nextTextField = [self.tableView viewWithTag:nextTag];
292         [nextTextField becomeFirstResponder];
293     }
294     else
295     {
296         [textField resignFirstResponder];
297     }
298     
299     return YES;
300 }
301
302 @end