Statistics
| Branch: | Tag: | Revision:

root / Classes / FolderDetailViewController.m @ 4b4b833e

History | View | Annotate | Download (14.7 kB)

1
//
2
//  FolderDetailViewController.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 "FolderDetailViewController.h"
39
#import "EditMetadataViewController.h"
40
#import "EditPermissionsViewController.h"
41
#import "StorageObject.h"
42
#import "APICallback.h"
43
#import "AccountManager.h"
44
#import "UIViewController+Conveniences.h"
45
#import "NSString+Conveniences.h"
46

    
47
#define kOverview 0
48
#define kMetadata 1
49
#define kPermissions 2
50

    
51
#define maxMetadataViewableLength 12
52

    
53

    
54
@implementation FolderDetailViewController
55

    
56
@synthesize account, container, folder, folderViewController;
57

    
58
#pragma mark - 
59
#pragma mark Memory management
60

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

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

    
80
#pragma mark - View lifecycle
81

    
82
- (void)viewDidLoad
83
{
84
    [super viewDidLoad];
85
    permissions = [[NSMutableDictionary alloc] init];
86
    if (folder.sharing.length > 0) {
87
        NSArray *sharingArray = [folder.sharing componentsSeparatedByString:@";"];
88
        for (NSString *typeSpecificPermissions in sharingArray) { 
89
            NSArray *array=[typeSpecificPermissions componentsSeparatedByString:@"="];
90
            NSString *permissionsType = [array objectAtIndex:0];
91
            if ([permissionsType hasPrefix:@" "])
92
                permissionsType = [permissionsType substringFromIndex:1];
93
            
94
            NSArray *users = [[array objectAtIndex:1] componentsSeparatedByString:@","];
95
            for (NSString *user in users) {
96
                [permissions setObject:permissionsType forKey:user];
97
            }
98
        }
99
    }
100
    
101
    folderIsReadOnly = NO;
102
    if (account.sharingAccount) { 
103
        if ([permissions count] > 0) {
104
            folderIsReadOnly = [[permissions objectForKey:[account username]] isEqualToString:@"read"];
105
        }
106
    }
107
    
108
    object = [[StorageObject alloc] init];
109
    object.name = folder.name;
110
    object.metadata = folder.metadata;
111
    object.fullPath = [folder fullPath];
112
    object.sharing = folder.sharing;
113
    object.contentType = folder.contentType;
114
}
115

    
116
- (void)viewDidUnload
117
{
118
    [super viewDidUnload];
119
}
120

    
121
- (void)viewWillAppear:(BOOL)animated
122
{
123
    [super viewWillAppear:animated];
124
    [self.tableView reloadData];
125
}
126

    
127
- (void)viewDidAppear:(BOOL)animated
128
{
129
    [super viewDidAppear:animated];
130
    if (folder.metadata == nil) {
131
        [self reloadMetadataSection];
132
    }
133
}
134

    
135
- (void)viewWillDisappear:(BOOL)animated
136
{
137
    [super viewWillDisappear:animated];
138
    folder.sharing = object.sharing;
139
}
140

    
141
- (void)viewDidDisappear:(BOOL)animated
142
{
143
    [super viewDidDisappear:animated];
144
}
145

    
146
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
147
    return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) || (toInterfaceOrientation == UIInterfaceOrientationPortrait);
148
}
149

    
150
#pragma mark - Table view data source
151

    
152
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
153
{
154
    return 3;
155
}
156

    
157
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
158
{
159
    if (section == kOverview)
160
        return 2;
161
    else if (section == kPermissions) {
162
        if (account.sharingAccount)
163
            return [permissions count];
164
        else
165
            return 1 + [permissions count];
166
    }
167
    else if (section == kMetadata)
168
        if (folderIsReadOnly)
169
            return [folder.metadata count];
170
        else
171
            return 1 + [folder.metadata count];     
172
        return 0;
173
}
174

    
175
- (CGFloat)findLabelHeight:(NSString*)text font:(UIFont *)font {
176
    CGSize textLabelSize;    
177
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
178
        textLabelSize = CGSizeMake(537.0, 9000.0f);
179
    } else {
180
        textLabelSize = CGSizeMake(221.0, 9000.0f);
181
    }
182

    
183
    CGSize stringSize = [text sizeWithFont:font constrainedToSize:textLabelSize lineBreakMode:UILineBreakModeCharacterWrap];
184
    return stringSize.height;
185
}
186

    
187
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
188
    CGFloat result;
189
    
190
    if (indexPath.section == kOverview) {
191
        if (indexPath.row == 0) {
192
            result = 22 + [self findLabelHeight:folder.name font:[UIFont systemFontOfSize:18.0]];
193
            
194
            return MAX(tableView.rowHeight, result);
195
        } else if (indexPath.row == 1) {
196
            NSString *folderFullPathToShow = folder.fullPath;
197
            if ([folderFullPathToShow hasPrefix:@"/"]) {
198
                folderFullPathToShow = [folderFullPathToShow substringFromIndex:1];
199
            }
200
            result = 22 + [self findLabelHeight:folderFullPathToShow font:[UIFont systemFontOfSize:18.0]];
201
        
202
            return MAX(tableView.rowHeight, result);
203
        }
204
    }
205
    
206
    return tableView.rowHeight;
207
}
208

    
209

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

    
218
        cell.textLabel.backgroundColor = [UIColor clearColor];
219
        cell.detailTextLabel.backgroundColor = [UIColor clearColor];
220
        cell.detailTextLabel.numberOfLines = 0;
221
        cell.detailTextLabel.lineBreakMode = UILineBreakModeWordWrap;
222
        cell.detailTextLabel.textAlignment = UITextAlignmentRight;
223
    }
224
    
225
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
226
        cell.backgroundColor = [UIColor colorWithRed:1 green:1 blue:1 alpha:0.8];
227
    }
228
    
229
    if (indexPath.section == kOverview) {
230
        cell.accessoryType = UITableViewCellAccessoryNone;
231
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
232
        cell.accessoryView = nil;
233
        if (indexPath.row == 0) {
234
            cell.textLabel.text = @"Name";
235
            cell.detailTextLabel.text = folder.name;
236
        } else if (indexPath.row == 1) {
237
            cell.textLabel.text = @"Full Path";
238
            NSString *folderFullPathToShow = folder.fullPath;
239
            if ([folderFullPathToShow hasPrefix:@"/"]) {
240
                folderFullPathToShow = [folderFullPathToShow substringFromIndex:1];
241
            }
242
            cell.detailTextLabel.text = folderFullPathToShow;
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
        }
281
        else {
282
            cell.selectionStyle = UITableViewCellSelectionStyleBlue;
283
            cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
284
        }
285
        cell.accessoryView = nil;
286
        
287
        if (indexPath.row == [permissions count]) {
288
            cell.textLabel.text = @"Share";
289
            cell.detailTextLabel.text = @""; 
290
        }
291
        else {
292
            NSString *user = [[permissions allKeys] objectAtIndex:indexPath.row];
293
            cell.textLabel.text = user;
294
            cell.detailTextLabel.text = [permissions objectForKey:user];
295
        }
296
    }
297

    
298
    return cell;
299
}
300

    
301

    
302
#pragma mark - Table view delegate
303

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

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

    
372
#pragma mark - 
373
#pragma mark Helper functions
374

    
375
- (void)reloadMetadataSection {
376
    NSString *activityMessage = @"Loading metadata...";
377
    ActivityIndicatorView *activityIndicatorView = [[ActivityIndicatorView alloc] initWithFrame:[ActivityIndicatorView frameForText:activityMessage] text:activityMessage];
378
    [activityIndicatorView addToView:self.view];         
379
    [[self.account.manager getObjectInfo:container object:object version:nil] 
380
     success:^(OpenStackRequest *request) {
381
         [activityIndicatorView removeFromSuperviewAndRelease];
382
         folder.metadata = [NSMutableDictionary dictionary];
383
         for (NSString *header in request.responseHeaders) {
384
             NSString *metadataKey;
385
             NSString *metadataValue;
386
             if ([header rangeOfString:@"X-Object-Meta-"].location != NSNotFound) {
387
                 metadataKey = [NSString decodeFromPercentEscape:[header substringFromIndex:14]];
388
                 metadataValue = [NSString decodeFromPercentEscape:[request.responseHeaders objectForKey:header]];
389
                 [folder.metadata setObject:metadataValue forKey:metadataKey];
390
             }
391
         }   
392
         object.metadata = folder.metadata;
393
         NSIndexSet *metadataSections = [NSIndexSet indexSetWithIndex:kMetadata];
394
         [self.tableView reloadSections:metadataSections withRowAnimation:UITableViewRowAnimationFade];
395
     }
396
     failure:^(OpenStackRequest *request) {
397
         [activityIndicatorView removeFromSuperviewAndRelease];
398
         [self alert:@"There was a problem retrieving the object's metadata." request:request]; 
399
     }];
400
}
401

    
402
@end