Statistics
| Branch: | Tag: | Revision:

root / Classes / UploadGenericFileViewController.m @ 3a8071d4

History | View | Annotate | Download (12.4 kB)

1
//
2
//  UploadGenericFileViewController.m
3
//  OpenStack
4
//
5
//  Created by Mike Mayo on 1/6/11.
6
//  Copyright 2011 __MyCompanyName__. All rights reserved.
7
//
8

    
9
#import "UploadGenericFileViewController.h"
10
#import "OpenStackAccount.h"
11
#import "AccountManager.h"
12
#import "Container.h"
13
#import "Folder.h"
14
#import "FolderViewController.h"
15
#import "ActivityIndicatorView.h"
16
#import "UIViewController+Conveniences.h"
17
#import "UIColor+MoreColors.h"
18
#import "StorageObject.h"
19
#import "OCMimeType.h"
20
#import "RSTextFieldCell.h"
21
#import "NSObject+Conveniences.h"
22
#import "APICallback.h"
23

    
24
#define kName 0
25
#define kContentType 1
26

    
27

    
28
@implementation UploadGenericFileViewController
29

    
30
@synthesize account, container, folder, folderViewController, data, format, contentType, contentTypeEditable;
31

    
32
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
33
    return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) || (toInterfaceOrientation == UIInterfaceOrientationPortrait);
34
}
35

    
36
#pragma mark -
37
#pragma mark View lifecycle
38

    
39
- (void)viewDidLoad {
40
    [super viewDidLoad];
41
    self.navigationItem.title = @"Add File";
42
    [self addSaveButton];
43
}
44

    
45
- (void)viewWillAppear:(BOOL)animated {
46
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
47
        nameTextField = [[UITextField alloc] initWithFrame:CGRectMake(98.0, 13.0, 400.0, 24.0)];
48
    } else {
49
        nameTextField = [[UITextField alloc] initWithFrame:CGRectMake(79.0, 13.0, 222.0, 24.0)];
50
    }    
51
    nameTextField.delegate = self;
52
    nameTextField.font = [UIFont systemFontOfSize:17.0];
53
    nameTextField.textColor = [UIColor value1DetailTextLabelColor];
54
    nameTextField.backgroundColor = [UIColor clearColor];
55
    nameTextField.textAlignment = UITextAlignmentRight;
56
    nameTextField.returnKeyType = UIReturnKeyDone;
57
    nameTextField.autocorrectionType = UITextAutocorrectionTypeNo;
58
    nameTextField.autocapitalizationType = UITextAutocapitalizationTypeNone;    
59
    nameTextField.placeholder = [NSString stringWithFormat:@"ios_upload_%.0f", [[NSDate date] timeIntervalSince1970]];
60
    
61
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
62
        formatLabel = [[UILabel alloc] initWithFrame:CGRectMake(41.0, 15.5, 458.0, 18.0)];
63
    } else {
64
        formatLabel = [[UILabel alloc] initWithFrame:CGRectMake(21.0, 15.5, 280.0, 18.0)];
65
    }    
66
    formatLabel.font = [UIFont systemFontOfSize:17.0];
67
    formatLabel.textColor = [UIColor value1DetailTextLabelColor];
68
    formatLabel.backgroundColor = [UIColor clearColor];
69
    formatLabel.textAlignment = UITextAlignmentRight;
70
    if (!self.format) {
71
        self.format = @"";
72
    } else if ([self.format isEqualToString:@".mov"]) {
73
        self.navigationItem.title = @"Add Video";        
74
    } else if ([self.format isEqualToString:@".txt"]) {
75
        self.navigationItem.title = @"Add Text File";
76
    }    
77

    
78
    formatLabel.text = self.format;
79
    
80
    // move the text field to make room for the numbers label
81
    CGSize size = [formatLabel.text sizeWithFont:formatLabel.font constrainedToSize:CGSizeMake(280.0, 900.0f)];
82
    
83
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
84
        nameTextField.frame = CGRectMake(98.0, 13.0, 400.0 - size.width, 24.0);
85
    } else {
86
        nameTextField.frame = CGRectMake(79.0, 13.0, 222.0 - size.width, 24.0);
87
    }    
88
    
89
        
90
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
91
        contentTypeTextField = [[UITextField alloc] initWithFrame:CGRectMake(79.0, 13.0, 400.0, 24.0)];
92
    } else {
93
        contentTypeTextField = [[UITextField alloc] initWithFrame:CGRectMake(79.0, 13.0, 222.0, 24.0)];
94
    }    
95
    contentTypeTextField.delegate = self;
96
    contentTypeTextField.font = [UIFont systemFontOfSize:17.0];
97
    contentTypeTextField.textColor = [UIColor value1DetailTextLabelColor];
98
    contentTypeTextField.backgroundColor = [UIColor clearColor];
99
    contentTypeTextField.textAlignment = UITextAlignmentRight;
100
    contentTypeTextField.returnKeyType = UIReturnKeyDone;
101
    contentTypeTextField.autocorrectionType = UITextAutocorrectionTypeNo;
102
    contentTypeTextField.autocapitalizationType = UITextAutocapitalizationTypeNone;
103
    
104
    if (contentTypeEditable) {
105
        if (self.contentType) {
106
            contentTypeTextField.text = self.contentType;
107
        } else {
108
            contentTypeTextField.text = [OCMimeType mimeTypeForFileExtension:[self.format substringFromIndex:1]];
109
        }
110
    } else {
111
        contentTypeTextField.enabled = NO;
112
        if (self.contentType) {
113
            contentTypeTextField.placeholder = self.contentType;
114
        } else {
115
            contentTypeTextField.placeholder = [OCMimeType mimeTypeForFileExtension:[self.format substringFromIndex:1]];
116
        }
117
    }
118
}
119

    
120
#pragma mark -
121
#pragma mark Table view data source
122

    
123
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
124
    return 2;
125
}
126

    
127
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
128
    if (section == kName) {
129
        return 2;
130
    } else {
131
        return 1;
132
    }
133
}
134

    
135
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section {
136
    if (section == kContentType) {
137
        return @"The Content Type (MIME Type) is a universal way to describe content regardless of the file extension.";
138
    } else {
139
        return @"";
140
    }
141
}
142

    
143
- (UITableViewCell *)tableView:(UITableView *)tableView textFieldCellForRowAtIndexPath:(NSIndexPath *)indexPath {
144
    if (indexPath.section == kName) {
145
        static NSString *CellIdentifier = @"NameCell";    
146
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
147
        if (cell == nil) {
148
            cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];
149
            cell.selectionStyle = UITableViewCellSelectionStyleNone;
150
            cell.textLabel.text = @"Name";
151
            [cell addSubview:nameTextField];
152
            [cell addSubview:formatLabel];
153
        }
154
        return cell;
155
    } else {
156
        static NSString *CellIdentifier = @"ContentTypeCell";
157
        RSTextFieldCell *cell = (RSTextFieldCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
158
        if (cell == nil) {
159
            cell = [[[RSTextFieldCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];
160
            cell.selectionStyle = UITableViewCellSelectionStyleNone;
161
            cell.modalPresentationStyle = UIModalPresentationFormSheet;
162
            cell.textLabel.text = @"Content Type";
163
            contentTypeTextField = cell.textField;
164
            if (contentTypeEditable) {
165
                if (self.contentType) {
166
                    contentTypeTextField.text = self.contentType;
167
                } else {
168
                    contentTypeTextField.text = [OCMimeType mimeTypeForFileExtension:[self.format substringFromIndex:1]];
169
                }
170
            } else {
171
                contentTypeTextField.enabled = NO;
172
                if (self.contentType) {
173
                    contentTypeTextField.placeholder = self.contentType;
174
                } else {
175
                    contentTypeTextField.placeholder = [OCMimeType mimeTypeForFileExtension:[self.format substringFromIndex:1]];
176
                }
177
            }
178
            
179
        }    
180
        return cell;
181
    }
182
}
183

    
184
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
185
    
186
    if (indexPath.section == kName && indexPath.row == 0) {
187
        return [self tableView:tableView textFieldCellForRowAtIndexPath:indexPath];
188
    } else if (indexPath.section == kContentType) {
189
        return [self tableView:tableView textFieldCellForRowAtIndexPath:indexPath];
190
    } else {
191
        static NSString *CellIdentifier = @"Cell";
192
        
193
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
194
        if (cell == nil) {
195
            cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];
196
        }
197
        
198
        cell.textLabel.text = @"Size";
199
        cell.detailTextLabel.text = [Container humanizedBytes:[data length]];
200
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
201
        cell.accessoryType = UITableViewCellAccessoryNone;
202
        
203
        return cell;
204
    }
205
}
206

    
207
#pragma mark -
208
#pragma mark Save Button
209

    
210
- (void)saveButtonPressed:(id)sender {
211
    [nameTextField resignFirstResponder];
212
    NSString *objectName;
213
    if (nameTextField.text && ![nameTextField.text isEqualToString:@""]) {
214
        objectName = [NSString stringWithFormat:@"%@%@", nameTextField.text, format];
215
    } else {
216
        objectName = [NSString stringWithFormat:@"%@%@", nameTextField.placeholder, format];
217
    }
218
    
219
    BOOL objectNameHasTrailingSlash = [objectName hasSuffix:@"/"];
220
    NSUInteger indexOfFirstSlash = [objectName rangeOfString:@"/"].location;
221
    
222
    if ((!objectNameHasTrailingSlash && indexOfFirstSlash != NSNotFound) || 
223
        (objectNameHasTrailingSlash && indexOfFirstSlash < objectName.length - 1)) {
224
        [self alert:@"Invalid folder name" message:@"'/' characters are only allowed at the end of folder names"];
225
        return;
226
    }
227

    
228
    if ([folderViewController.folder.objects objectForKey:objectName] && !allowOverwrite) {
229
        NSString *alertMessage = [NSString stringWithFormat:@"An object with path '%@' in the container '%@' already exists, do you want to replace it?",objectName, folderViewController.container.name];
230
        NSString *alertTitle = @"Apply changes";
231
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:alertTitle
232
                                                        message:alertMessage
233
                                                       delegate:self
234
                                              cancelButtonTitle:@"Cancel"
235
                                              otherButtonTitles:@"OK", nil];
236
        [alert show];
237
        [alert release];
238
        return;
239
    }
240
    [activityIndicatorView release];
241
    activityIndicatorView = [[ActivityIndicatorView alloc] initWithFrame:[ActivityIndicatorView frameForText:@"Uploading..." withProgress:YES] text:@"Uploading..." withProgress:YES];
242
    [activityIndicatorView addToView:self.view];
243
    
244
    StorageObject *object = [[StorageObject alloc] init];
245
    object.name = objectName;
246
    object.fullPath = [NSString stringWithFormat:@"%@/%@", [folder fullPath], object.name];
247
    object.fullPath = [object.fullPath substringFromIndex:1];
248
    object.contentType = contentTypeTextField.text;
249
    
250
    if (!contentType) {
251
        object.contentType = @"application/octet-stream";
252
    }
253
    
254
    object.data = data;
255
    object.bytes = [data length];
256
    
257
    [[self.account.manager writeObject:self.container object:object downloadProgressDelegate:activityIndicatorView.progressView]
258
     success:^(OpenStackRequest *request) {
259
         [activityIndicatorView removeFromSuperview];
260
         object.data = nil;
261
         object.sharing = folder.sharing;
262
         BOOL currentFolderIsRoot = NO;
263
         if ([folderViewController.folder isEqual:container.rootFolder]) {
264
             currentFolderIsRoot = YES;
265
         }
266
         [folder.objects setObject:object forKey:object.name];
267
         [folderViewController.tableView reloadData];
268
         if (currentFolderIsRoot) {
269
             container.count += 1;
270
             container.rootFolder = folder;
271
             [self.account.containers setObject:container forKey:container.name];
272
         }
273
         if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
274
             [folderViewController setDetailViewController];
275
         allowOverwrite = NO;
276
         [self dismissModalViewControllerAnimated:YES];
277
     }
278
     failure:^(OpenStackRequest *request) {
279
         allowOverwrite = NO;
280
         [activityIndicatorView removeFromSuperview];
281
         [self alert:@"There was a problem uploading the file." request:request];
282
     }];    
283
}
284

    
285
#pragma mark - Alertview delegate
286

    
287
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
288
{
289
    if (buttonIndex == 1) {
290
        allowOverwrite = YES;
291
        [self saveButtonPressed:nil];
292
    } 
293
}
294

    
295

    
296
#pragma mark -
297
#pragma mark Text Field Delegate
298

    
299
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
300
    [textField resignFirstResponder];
301
    return NO;
302
}
303

    
304
#pragma mark -
305
#pragma mark Memory management
306

    
307
- (void)dealloc {
308
    [account release];
309
    [container release];
310
    [folder release];
311
    [folderViewController release];
312
    [data release];
313
    [format release];
314
    [contentType release];
315
    [activityIndicatorView release];
316
    [super dealloc];
317
}
318

    
319

    
320
@end
321