Statistics
| Branch: | Tag: | Revision:

root / Classes / EditMetadataViewController.m @ 45f2fce6

History | View | Annotate | Download (19.1 kB)

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
#import "FolderViewController.h"
42
#import "Folder.h"
43
#import "PithosUtilities.h"
44

    
45

    
46

    
47
@implementation EditMetadataViewController
48

    
49

    
50
@synthesize container, account, object;
51

    
52
@synthesize metadataKey;
53
@synthesize metadataValue;
54
@synthesize removeMetadataEnabled, objectIsFolder, folderViewController, objectIsContainer;
55

    
56
#define kMetadata 0 
57
#define kSaveMedata 1
58
#define kDeleteMetadata 2
59

    
60

    
61
- (void)dealloc
62
{
63
    [account release];
64
    [container release];
65
    [object release];
66
    [metadataKey release];
67
    [metadataValue release];
68
    [super dealloc];
69
}
70

    
71
- (void)didReceiveMemoryWarning
72
{
73
    // Releases the view if it doesn't have a superview.
74
    [super didReceiveMemoryWarning];
75
    
76
    // Release any cached data, images, etc that aren't in use.
77
}
78

    
79
#pragma mark - View lifecycle
80

    
81
- (void)viewDidLoad
82
{
83
    [super viewDidLoad];
84
}
85

    
86
- (void)viewDidUnload
87
{
88
    [super viewDidUnload];
89
}
90

    
91
- (void)viewWillAppear:(BOOL)animated
92
{    
93
    [super viewWillAppear:animated];
94
}
95

    
96
- (void)viewDidAppear:(BOOL)animated
97
{
98
    [super viewDidAppear:animated];
99
}
100

    
101
- (void)viewWillDisappear:(BOOL)animated
102
{
103
    [super viewWillDisappear:animated];
104
}
105

    
106
- (void)viewDidDisappear:(BOOL)animated
107
{
108
    [super viewDidDisappear:animated];
109
}
110

    
111
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
112
    return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) || (toInterfaceOrientation == UIInterfaceOrientationPortrait);
113
}
114

    
115
#pragma mark - Table view data source
116

    
117
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
118
{
119
    return (removeMetadataEnabled)? 3:2;
120
}
121

    
122
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
123
{
124
    if (section == kMetadata)
125
        return 2;
126
    else
127
        return 1;
128
}
129

    
130
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
131
{
132
    static NSString *CellIdentifier = @"Cell";
133
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
134
    if (cell == nil) {
135
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
136
    }
137
                
138
    if (indexPath.section == kMetadata) {
139
        UITextField *textField = nil;
140
        for (id subView in cell.contentView.subviews) {
141
            if ([subView isKindOfClass:[UITextField class]]) {
142
                textField = (UITextField *)subView;
143
            }
144
        }
145
        
146
        if (textField == nil) {
147
            CGRect bounds = [cell.contentView bounds];
148
            CGRect rect = CGRectInset(bounds, 10.0, 10.0);                        
149
            textField = [[UITextField alloc] initWithFrame:rect];
150
            [textField setFrame:rect];
151
        }
152
        [textField setClearButtonMode:UITextFieldViewModeWhileEditing];
153
        [textField setBackgroundColor:[UIColor clearColor]];
154
        [textField setOpaque:YES];
155
        [textField setAutocorrectionType:UITextAutocorrectionTypeNo];
156
        [textField setAutocapitalizationType:UITextAutocapitalizationTypeNone];
157
        [textField setDelegate:self];
158
        textField.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
159

    
160
        if (indexPath.row == 0) {
161
            [textField setReturnKeyType:UIReturnKeyNext];
162
            textField.placeholder = @"Key";
163
            textField.text = self.metadataKey;
164
            textField.tag = 0;
165
        }
166
        else if (indexPath.row == 1) {
167
            textField.placeholder = @"Value";
168
            textField.text = self.metadataValue;
169
            textField.tag = 1;
170
        }
171
            
172
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
173
        [cell.contentView addSubview:textField];
174
    }
175
    else if (indexPath.section == kSaveMedata) 
176
        cell.textLabel.text = @"Save";
177
    else if (indexPath.section == kDeleteMetadata)
178
        cell.textLabel.text = @"Remove";
179
    
180
    return cell;
181
}
182

    
183

    
184
#pragma mark - Table view delegate
185

    
186
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
187
{
188

    
189
    
190
    if (indexPath.section != kMetadata)
191
        [self.view endEditing:YES];
192
    
193
    NSString *activityMessage;
194
    NSIndexPath *keyCellIndexPath;
195
    NSIndexPath *valueCellIndexPath;
196
    UITableViewCell *cell;
197
    
198
    switch (indexPath.section) {
199
        case kSaveMedata:
200
            keyCellIndexPath = [NSIndexPath indexPathForRow:0 inSection:kMetadata];
201
            cell = [self.tableView cellForRowAtIndexPath:keyCellIndexPath];
202
            UITextField *textField = [[cell.contentView subviews] objectAtIndex:0];
203
            newMetadataKey = textField.text;
204
        
205
            if ([newMetadataKey length] == 0
206
                || [[newMetadataKey stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length] == 0) {
207
                [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
208
                [self alert:@"Invalid input" message:@"Metadata key cannot be empty"];
209
                return;
210
            }
211
            
212
            valueCellIndexPath = [NSIndexPath indexPathForRow:1 inSection:kMetadata];
213
            cell = [self.tableView cellForRowAtIndexPath:valueCellIndexPath];
214
            textField = [[cell.contentView subviews] objectAtIndex:0];
215
            newMetadataValue = textField.text;
216
            
217
            [object.metadata removeObjectForKey:metadataKey];
218
            [object.metadata setObject:newMetadataValue forKey:newMetadataKey];
219
            
220
            if (objectIsFolder && ![PithosUtilities isContentTypeDirectory:object.contentType]) {
221
                if ([folderViewController.folder.objects objectForKey:object.name]) {
222
                    NSString *alertMessage = [NSString stringWithFormat:@"In order to apply the changes in '%@', the object at the same path must be replaced. Continue?",object.name];
223
                    NSString *alertTitle = @"Apply changes";
224
                    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:alertTitle
225
                                                                    message:alertMessage
226
                                                                   delegate:self
227
                                                          cancelButtonTitle:@"Cancel"
228
                                                          otherButtonTitles:@"OK", nil];
229
                    [alert show];
230
                    return;
231
                } else {
232
                    activityMessage = @"Saving metadata...";
233
                    activityIndicatorView = [[ActivityIndicatorView alloc] initWithFrame:[ActivityIndicatorView frameForText:activityMessage] text:activityMessage];
234
                    [activityIndicatorView addToView:self.view];
235
                    
236
                    object.name = object.fullPath;
237
                    object.contentType = @"application/directory";
238
                    object.data = [NSData data];
239
                    [self addNewFolderRequestObservers];
240
                    [self.account.manager writeObject:self.container object:object downloadProgressDelegate:nil];  
241
                    return;
242
                }
243
            }
244
            
245
            activityMessage = @"Saving metadata";
246
            activityIndicatorView = [[ActivityIndicatorView alloc] initWithFrame:[ActivityIndicatorView frameForText:activityMessage] text:activityMessage];
247
            [activityIndicatorView addToView:self.view];
248

    
249
            [self.account.manager writeObjectMetadata:container object:object];
250
            successObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"writeObjectMetadataSucceeded"
251
                                                                                object:object
252
                                                                                 queue:[NSOperationQueue mainQueue]
253
                                                                            usingBlock:^(NSNotification *notification)
254
                               {
255
                                   self.metadataKey = newMetadataKey;
256
                                   self.metadataValue = newMetadataValue;
257
                                   removeMetadataEnabled = YES;
258
                                   [self.tableView reloadData];
259
                                   [activityIndicatorView removeFromSuperviewAndRelease];
260
                                   [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
261
                                   if (objectIsContainer) {
262
                                       container.metadata = object.metadata;
263
                                       [self.account.containers setObject:container forKey:container.name];
264
                                   }
265
                                   [[NSNotificationCenter defaultCenter] removeObserver:successObserver];
266
                               }];
267
            
268
            failureObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"writeObjectMetadataFailed" 
269
                                                                                object:object 
270
                                                                                 queue:[NSOperationQueue mainQueue] 
271
                                                                            usingBlock:^(NSNotification *notification)
272
                               {
273
                                   [object.metadata removeObjectForKey:newMetadataKey];
274
                                   [object.metadata setObject:metadataValue forKey:metadataKey];
275
                                   [activityIndicatorView removeFromSuperviewAndRelease];
276
                                   [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
277
                                   [self alert:@"There was a problem saving the metadata." request:[notification.userInfo objectForKey:@"request"]];
278
                                   
279
                                   [[NSNotificationCenter defaultCenter] removeObserver:failureObserver];
280
                               }];
281
            
282
            break;
283
        case kDeleteMetadata:
284
            activityMessage = @"Deleting metadata";
285
            activityIndicatorView = [[ActivityIndicatorView alloc] initWithFrame:[ActivityIndicatorView frameForText:activityMessage] text:activityMessage];
286
            [activityIndicatorView addToView:self.view];
287

    
288
            [object.metadata removeObjectForKey:metadataKey];
289
            [self.account.manager writeObjectMetadata:container object:object];
290
            successObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"writeObjectMetadataSucceeded"
291
                                                                                object:object
292
                                                                                 queue:[NSOperationQueue mainQueue]
293
                                                                            usingBlock:^(NSNotification *notification)
294
                               {
295
                                   [activityIndicatorView removeFromSuperviewAndRelease];
296
                                   [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
297
                                   self.metadataKey = @"";
298
                                   self.metadataValue = @"";
299
                                   removeMetadataEnabled = NO;
300
                                   [self.tableView reloadData];
301
                                   if (objectIsContainer) {
302
                                       container.metadata = object.metadata;
303
                                       [self.account.containers setObject:container forKey:container.name];
304
                                   }
305
                                   [[NSNotificationCenter defaultCenter] removeObserver:successObserver];
306
                               }];
307
            
308
            failureObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"writeObjectMetadataFailed" 
309
                                                                                object:object 
310
                                                                                 queue:[NSOperationQueue mainQueue] 
311
                                                                            usingBlock:^(NSNotification *notification)
312
                               {
313
                                   [object.metadata setObject:metadataValue forKey:metadataKey];
314
                                   [activityIndicatorView removeFromSuperviewAndRelease];
315
                                   [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
316
                                   [self alert:@"There was a problem saving the metadata." request:[notification.userInfo objectForKey:@"request"]];
317
                                   
318
                                   [[NSNotificationCenter defaultCenter] removeObserver:failureObserver];
319
                               }];
320

    
321
            break;
322
    }
323
}
324

    
325
#pragma mark - Alertview delegate
326

    
327
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
328
{
329
    if (buttonIndex == 1) {
330
        NSString *activityMessage = @"Applying permissions...";
331
        
332
        activityIndicatorView = [[ActivityIndicatorView alloc] initWithFrame:[ActivityIndicatorView frameForText:activityMessage] text:activityMessage];
333
        [activityIndicatorView addToView:self.view];
334
        
335
        object.name = object.fullPath;
336
        object.contentType = @"application/directory";
337
        object.data = [NSData data];
338
        [self addNewFolderRequestObservers];
339
        [self.account.manager writeObject:self.container object:object downloadProgressDelegate:nil];        
340
        
341
    } else {
342
        [self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];
343
    }
344
}
345

    
346
#pragma mark - Textfield delegate
347

    
348

    
349
- (BOOL)textFieldShouldReturn:(UITextField *)textField
350
{
351
    
352
    if ([textField returnKeyType] == UIReturnKeyNext)
353
    {
354
        if ([textField.text length] == 0
355
            || [[textField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length] == 0) {
356
            [self alert:@"Invalid input" message:@"Metadata key cannot be empty"];
357
        }
358

    
359
        NSInteger nextTag = [textField tag] + 1;
360
        UIView *nextTextField = [self.tableView viewWithTag:nextTag];
361
        [nextTextField becomeFirstResponder];
362
    }
363
    else
364
    {
365
        [textField resignFirstResponder];
366
    }
367
    
368
    return YES;
369
}
370

    
371
#pragma mark - add observers
372

    
373
- (void)addNewFolderRequestObservers {
374
    addFolderSuccessObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"writeObjectSucceeded" object:object 
375
                                                                                  queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notification)
376
                                {
377
                                    Folder *newFolder = [[Folder alloc] init];
378
                                    newFolder.name = [[object.name componentsSeparatedByString:@"/"] lastObject];
379
                                    newFolder.parent = folderViewController.folder;
380
                                    newFolder.sharing = folderViewController.folder.sharing;
381
                                    newFolder.metadata = object.metadata;
382
                                    [folderViewController.folder.folders setObject:newFolder forKey:newFolder.name];
383
                                    [activityIndicatorView removeFromSuperviewAndRelease];
384
                                    [newFolder release];
385
                                    self.metadataKey = newMetadataKey;
386
                                    self.metadataValue = newMetadataValue;
387
                                    removeMetadataEnabled = YES;
388
                                    [self.tableView reloadData];
389
                                    [self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];
390
                                    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
391
                                        [self.folderViewController refreshButtonPressed:nil];
392
                                    }
393
                                    else {
394
                                        self.folderViewController.needsRefreshing = YES;
395
                                    }
396
                                    [[NSNotificationCenter defaultCenter] removeObserver:addFolderSuccessObserver];
397
                                }];
398
    
399
    addFolderFailureObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"writeObjectFailed" object:object 
400
                                                                                  queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notification)
401
                                {         
402
                                    [object.metadata removeObjectForKey:newMetadataKey];
403
                                    [object.metadata setObject:metadataValue forKey:metadataKey];
404
                                    [activityIndicatorView removeFromSuperviewAndRelease];
405
                                    [self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];
406
                                    [self.tableView reloadData];
407
                                    [self alert:@"There was a problem saving the metadata." request:[notification.userInfo objectForKey:@"request"]];
408
                                    
409
                                    [[NSNotificationCenter defaultCenter] removeObserver:addFolderFailureObserver];
410
                                }];
411
    
412

    
413
}
414

    
415
@end