Statistics
| Branch: | Tag: | Revision:

root / Classes / FolderDetailViewController.m @ ea3a6bba

History | View | Annotate | Download (15.6 kB)

1
//
2
//  FolderDetailViewController.m
3
//  pithos-ios
4
//
5
// Copyright 2011-2013 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 "FolderDetailViewController.h"
39
#import "EditMetadataViewController.h"
40
#import "EditPermissionsViewController.h"
41
#import "OpenStackAccount.h"
42
#import "Container.h"
43
#import "Folder.h"
44
#import "StorageObject.h"
45
#import "ActivityIndicatorView.h"
46
#import "APICallback.h"
47
#import "AccountManager.h"
48
#import "UIViewController+Conveniences.h"
49
#import "NSString+Conveniences.h"
50

    
51
#define kOverview 0
52
#define kMetadata 1
53
#define kPermissions 2
54

    
55
#define maxMetadataViewableLength 12
56

    
57
@implementation FolderDetailViewController
58

    
59
@synthesize account, container, folder, folderViewController, permissions;
60

    
61
#pragma mark - View lifecycle
62

    
63
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
64
    return ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) || (toInterfaceOrientation == UIInterfaceOrientationPortrait);
65
}
66

    
67
- (void)viewDidLoad {
68
    [super viewDidLoad];
69
    self.permissions = [folder.folderObject permissions];
70
    folderIsReadOnly = NO;
71
    if (account.sharingAccount && permissions.count) {
72
        folderIsReadOnly = ![[permissions objectForKey:account.username] isEqualToString:@"write"];
73
    }
74
    
75
    object = [[StorageObject alloc] init];
76
    object.name = folder.name;
77
    object.metadata = folder.metadata;
78
    object.fullPath = [folder fullPath];
79
    object.sharing = folder.sharing;
80
    object.contentType = folder.contentType;
81
}
82

    
83
- (void)viewWillAppear:(BOOL)animated {
84
    [super viewWillAppear:animated];
85
    [self.tableView reloadData];
86
}
87

    
88
- (void)viewDidAppear:(BOOL)animated {
89
    [super viewDidAppear:animated];
90
    if (folder.metadata == nil) {
91
        [self reloadMetadataSection];
92
    } else {
93
        [self updatePermissionsUserCatalog];
94
    }
95
}
96

    
97
- (void)viewWillDisappear:(BOOL)animated {
98
    [super viewWillDisappear:animated];
99
    folder.sharing = object.sharing;
100
}
101

    
102
#pragma mark - Memory management
103

    
104
- (void)dealloc {
105
    [object release];
106
    [account release];
107
    [container release];
108
    [folderViewController release];
109
    [folder release];
110
    [permissions release];
111
    [super dealloc];
112
}
113

    
114
#pragma mark - Internal
115

    
116
- (void)updatePermissionsUserCatalog {
117
    NSMutableArray *UUIDs = [NSMutableArray arrayWithCapacity:permissions.count];
118
    for (NSString *user in [permissions allKeys]) {
119
        NSRange rangeOfColumn = [user rangeOfString:@":"];
120
        NSString *UUID = (rangeOfColumn.location == NSNotFound) ? user : [user substringToIndex:rangeOfColumn.location];
121
        if (![UUID isEqualToString:@"*"]) {
122
            [UUIDs addObject:UUID];
123
        }
124
    }
125
    if (UUIDs.count) {
126
        __block ActivityIndicatorView *activityIndicatorView = [ActivityIndicatorView activityIndicatorViewWithText:@"Loading permissions..."
127
                                                                                                       andAddToView:self.view];
128
        [[self.account.manager userCatalogForDisplaynames:nil UUIDs:UUIDs]
129
         success:^(OpenStackRequest *request) {
130
             [activityIndicatorView stopAnimatingAndRemoveFromSuperview];
131
             [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:kPermissions] withRowAnimation:UITableViewRowAnimationNone];
132
         }
133
         failure:^(OpenStackRequest *request) {
134
             [activityIndicatorView stopAnimatingAndRemoveFromSuperview];
135
         }];
136
    }
137
}
138
#pragma mark - Actions
139

    
140
- (void)reloadMetadataSection {
141
    __block ActivityIndicatorView *activityIndicatorView = [ActivityIndicatorView activityIndicatorViewWithText:@"Loading metadata..."
142
                                                                                                   andAddToView:self.view];
143
    [[self.account.manager getObjectInfo:container object:object version:nil]
144
     success:^(OpenStackRequest *request) {
145
         [activityIndicatorView stopAnimatingAndRemoveFromSuperview];
146
         folder.metadata = [NSMutableDictionary dictionary];
147
         for (NSString *header in request.responseHeaders) {
148
             NSString *metadataKey;
149
             NSString *metadataValue;
150
             if ([header rangeOfString:@"X-Object-Meta-"].location != NSNotFound) {
151
                 metadataKey = [NSString decodeFromPercentEscape:[header substringFromIndex:14]];
152
                 metadataValue = [NSString decodeFromPercentEscape:[request.responseHeaders objectForKey:header]];
153
                 [folder.metadata setObject:metadataValue forKey:metadataKey];
154
             }
155
         }
156
         object.metadata = folder.metadata;
157
         [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:kMetadata] withRowAnimation:UITableViewRowAnimationFade];
158
         [self updatePermissionsUserCatalog];
159
     }
160
     failure:^(OpenStackRequest *request) {
161
         [activityIndicatorView stopAnimatingAndRemoveFromSuperview];
162
         [self alert:@"There was a problem retrieving the object's metadata." request:request];
163
     }];
164
}
165

    
166
#pragma mark - UITableViewDataSource
167

    
168
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
169
    return 3;
170
}
171

    
172
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
173
    if (section == kOverview) {
174
        return (folder.lastModifiedString ? 3 : 2);
175
    } else if (section == kPermissions) {
176
        if (account.sharingAccount) {
177
            return permissions.count;
178
        } else {
179
            return (permissions.count + 1);
180
        }
181
    } else if (section == kMetadata) {
182
        if (folderIsReadOnly) {
183
            return [folder.metadata count];
184
        } else {
185
            return ([folder.metadata count] + 1);
186
        }
187
    }
188
    return 0;
189
}
190

    
191
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
192
    CGFloat result = tableView.rowHeight;
193
    if ((indexPath.section == kOverview) && ((indexPath.row == 0) || (indexPath.row == 1))) {
194
        NSString *text;
195
        if (indexPath.row == 0) {
196
            text = folder.name;
197
        } else {
198
            text = folder.fullPath;
199
            if ([text hasPrefix:@"/"]) {
200
                text = [text substringFromIndex:1];
201
            }
202
        }
203
        result = 22.0 + [text sizeWithFont:[UIFont systemFontOfSize:18.0]
204
                         constrainedToSize:(([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) ?
205
                                            CGSizeMake(537.0, 9000.0) :
206
                                            CGSizeMake(221.0, 9000.0))
207
                             lineBreakMode:UILineBreakModeCharacterWrap].height;
208
    }
209
    return MAX(tableView.rowHeight, result);
210
}
211

    
212
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
213
    static NSString *CellIdentifier = @"Cell";
214
    
215
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
216
    if (cell == nil) {
217
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];
218

    
219
        cell.textLabel.backgroundColor = [UIColor clearColor];
220
        cell.detailTextLabel.backgroundColor = [UIColor clearColor];
221
        cell.detailTextLabel.numberOfLines = 0;
222
        cell.detailTextLabel.lineBreakMode = UILineBreakModeWordWrap;
223
        cell.detailTextLabel.textAlignment = UITextAlignmentRight;
224
    }
225
    
226
    if (indexPath.section == kOverview) {
227
        cell.accessoryType = UITableViewCellAccessoryNone;
228
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
229
        cell.accessoryView = nil;
230
        if (indexPath.row == 0) {
231
            cell.textLabel.text = @"Name";
232
            cell.detailTextLabel.text = folder.name;
233
        } else if (indexPath.row == 1) {
234
            cell.textLabel.text = @"Full Path";
235
            NSString *folderFullPathToShow = folder.fullPath;
236
            if ([folderFullPathToShow hasPrefix:@"/"]) {
237
                folderFullPathToShow = [folderFullPathToShow substringFromIndex:1];
238
            }
239
            cell.detailTextLabel.text = folderFullPathToShow;
240
        } else if (indexPath.row == 2) {
241
            cell.textLabel.text = @"Last Modified";
242
            cell.detailTextLabel.text = folder.lastModifiedString;
243
        }
244
    } else if (indexPath.section == kMetadata) {
245
        if (folderIsReadOnly) {
246
            cell.accessoryType = UITableViewCellAccessoryNone;
247
            cell.selectionStyle = UITableViewCellSelectionStyleNone;
248
            cell.userInteractionEnabled = NO;
249
        }
250
        else {
251
            cell.selectionStyle = UITableViewCellSelectionStyleBlue;
252
            cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
253
        }
254
        cell.accessoryView = nil;
255
        if (indexPath.row == [folder.metadata count]) {
256
            cell.textLabel.text = @"Add Metadata";
257
            cell.detailTextLabel.text = @"";
258
        } else {
259
            NSString *key = [[folder.metadata allKeys] objectAtIndex:indexPath.row];
260
            NSString *value = [folder.metadata objectForKey:key];
261
            NSString *metadataKeyCellText = key;
262
            NSString *metadataValueCellText = value;
263
            if ([metadataKeyCellText length] > maxMetadataViewableLength) {
264
                metadataKeyCellText = [metadataKeyCellText substringToIndex:(maxMetadataViewableLength - 3)];
265
                metadataKeyCellText = [metadataKeyCellText stringByAppendingString:@"..."];
266
            }
267
            if ([metadataValueCellText length] > maxMetadataViewableLength) {
268
                metadataValueCellText = [metadataValueCellText substringToIndex:(maxMetadataViewableLength - 3)];
269
                metadataValueCellText = [metadataValueCellText stringByAppendingString:@"..."];
270
            }
271

    
272
            cell.textLabel.text = metadataKeyCellText;
273
            cell.detailTextLabel.text = metadataValueCellText;
274
        }
275
    } else if (indexPath.section == kPermissions) {
276
        if (account.sharingAccount) {
277
            cell.accessoryType = UITableViewCellAccessoryNone;
278
            cell.selectionStyle = UITableViewCellSelectionStyleNone;
279
            cell.userInteractionEnabled = NO;
280
        } else {
281
            cell.selectionStyle = UITableViewCellSelectionStyleBlue;
282
            cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
283
        }
284
        cell.accessoryView = nil;
285
        
286
        if (indexPath.row == permissions.count) {
287
            cell.textLabel.text = @"Share";
288
            cell.detailTextLabel.text = @""; 
289
        } else {
290
            NSString *user = [[[permissions allKeys] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)] objectAtIndex:indexPath.row];
291
            NSRange rangeOfColumn = [user rangeOfString:@":"];
292
            NSString *UUID = (rangeOfColumn.location == NSNotFound) ? user : [user substringToIndex:rangeOfColumn.location];
293
            NSString *group = ((rangeOfColumn.location == NSNotFound) || (rangeOfColumn.location == user.length - 1)) ? nil : [user substringFromIndex:(rangeOfColumn.location + 1)];
294
            NSMutableString *displayname = [NSMutableString stringWithString:[account displaynameForUUID:UUID safe:YES]];
295
            if (group) {
296
                [displayname appendFormat:@":%@", group];
297
            }
298
            cell.textLabel.text = displayname;
299
            
300
            cell.detailTextLabel.numberOfLines = 1;
301
            cell.detailTextLabel.lineBreakMode = UILineBreakModeTailTruncation;
302
            cell.detailTextLabel.text = ([[permissions objectForKey:user] isEqualToString:@"write"] ? @"Read/Write" : @"Read Only");
303
        }
304
    }
305

    
306
    return cell;
307
}
308

    
309
#pragma mark - UITableViewDelegate
310

    
311
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
312
    if (indexPath.section == kMetadata) {
313
        EditMetadataViewController *vc = [[EditMetadataViewController alloc] initWithNibName:@"EditMetadataViewController" bundle:nil];
314
        NSString *metadataKey;
315
        NSString *metadataValue;
316
        
317
        if (indexPath.row == [self.folder.metadata count]) {
318
            metadataKey = @"";
319
            metadataValue = @"";
320
            vc.removeMetadataEnabled = FALSE;
321
            vc.navigationItem.title = @"Add Metadata";
322
        } else {
323
            metadataKey = [[self.folder.metadata allKeys] objectAtIndex:indexPath.row];
324
            metadataValue = [self.folder.metadata objectForKey:metadataKey];
325
            vc.removeMetadataEnabled = TRUE;
326
            vc.navigationItem.title = @"Edit Metadata";
327
        }
328
                
329
        vc.metadataKey = metadataKey;
330
        vc.metadataValue = metadataValue;
331
        vc.account = account;
332
        vc.container = container;
333
        vc.object = object;
334
        vc.objectIsFolder = YES;
335
        vc.folderViewController = folderViewController;
336

    
337
        [self.navigationController pushViewController:vc animated:YES];
338
        [vc release];
339
    } else if (indexPath.section == kPermissions) {
340
        EditPermissionsViewController *vc = [[EditPermissionsViewController alloc] initWithNibName:@"EditPermissionsViewController" bundle:nil];
341
        NSString *user;
342
        
343
        if (indexPath.row == permissions.count) {
344
            user = @"";
345
            vc.removePermissionsEnabled = NO;
346
            vc.navigationItem.title = @"Add Permission";
347
        } else {
348
            user = [[[permissions allKeys] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)] objectAtIndex:indexPath.row];
349
            NSString *userPermissions = [permissions objectForKey:user];
350
            if ([userPermissions rangeOfString:@"read"].location != NSNotFound) {
351
                vc.readPermissionSelected = YES;
352
            } else {
353
                vc.readPermissionSelected = NO;
354
            }
355
            if ([userPermissions rangeOfString:@"write"].location != NSNotFound) {
356
                vc.writePermissionSelected = YES;
357
            } else {
358
                vc.writePermissionSelected = NO;
359
            }
360
            vc.removePermissionsEnabled = YES;
361
            vc.navigationItem.title = @"Edit Permission";
362
        }
363
        
364
        vc.permissionUser = user;
365
        vc.permissions = permissions;
366
        vc.account = account;
367
        vc.container = container;
368
        vc.object = object;
369
        vc.objectIsFolder = YES;
370
        vc.folderViewController = folderViewController;
371
        [self.navigationController pushViewController:vc animated:YES];
372
        [vc release];
373
    } 
374
}
375

    
376
@end