root / Classes / UploadGenericFileViewController.m @ 45f2fce6
History | View | Annotate | Download (12.6 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 |
|
23 |
#define kName 0 |
24 |
#define kContentType 1 |
25 |
|
26 |
|
27 |
@implementation UploadGenericFileViewController |
28 |
|
29 |
@synthesize account, container, folder, folderViewController, data, format, contentType, contentTypeEditable; |
30 |
|
31 |
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation { |
32 |
return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) || (toInterfaceOrientation == UIInterfaceOrientationPortrait); |
33 |
} |
34 |
|
35 |
#pragma mark - |
36 |
#pragma mark View lifecycle |
37 |
|
38 |
- (void)viewDidLoad { |
39 |
[super viewDidLoad]; |
40 |
self.navigationItem.title = @"Add File"; |
41 |
[self addSaveButton]; |
42 |
} |
43 |
|
44 |
- (void)viewWillAppear:(BOOL)animated { |
45 |
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { |
46 |
nameTextField = [[UITextField alloc] initWithFrame:CGRectMake(98.0, 13.0, 400.0, 24.0)]; |
47 |
} else { |
48 |
nameTextField = [[UITextField alloc] initWithFrame:CGRectMake(79.0, 13.0, 222.0, 24.0)]; |
49 |
} |
50 |
nameTextField.delegate = self; |
51 |
nameTextField.font = [UIFont systemFontOfSize:17.0]; |
52 |
nameTextField.textColor = [UIColor value1DetailTextLabelColor]; |
53 |
nameTextField.backgroundColor = [UIColor clearColor]; |
54 |
nameTextField.textAlignment = UITextAlignmentRight; |
55 |
nameTextField.returnKeyType = UIReturnKeyDone; |
56 |
nameTextField.autocorrectionType = UITextAutocorrectionTypeNo; |
57 |
nameTextField.autocapitalizationType = UITextAutocapitalizationTypeNone; |
58 |
nameTextField.placeholder = [NSString stringWithFormat:@"ios_upload_%.0f", [[NSDate date] timeIntervalSince1970]]; |
59 |
|
60 |
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { |
61 |
formatLabel = [[UILabel alloc] initWithFrame:CGRectMake(41.0, 15.5, 458.0, 18.0)]; |
62 |
} else { |
63 |
formatLabel = [[UILabel alloc] initWithFrame:CGRectMake(21.0, 15.5, 280.0, 18.0)]; |
64 |
} |
65 |
formatLabel.font = [UIFont systemFontOfSize:17.0]; |
66 |
formatLabel.textColor = [UIColor value1DetailTextLabelColor]; |
67 |
formatLabel.backgroundColor = [UIColor clearColor]; |
68 |
formatLabel.textAlignment = UITextAlignmentRight; |
69 |
if (!self.format) { |
70 |
self.format = @""; |
71 |
} else if ([self.format isEqualToString:@".mov"]) { |
72 |
self.navigationItem.title = @"Add Video"; |
73 |
} else if ([self.format isEqualToString:@".txt"]) { |
74 |
self.navigationItem.title = @"Add Text File"; |
75 |
} |
76 |
|
77 |
formatLabel.text = self.format; |
78 |
|
79 |
// move the text field to make room for the numbers label |
80 |
CGSize size = [formatLabel.text sizeWithFont:formatLabel.font constrainedToSize:CGSizeMake(280.0, 900.0f)]; |
81 |
|
82 |
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { |
83 |
nameTextField.frame = CGRectMake(98.0, 13.0, 400.0 - size.width, 24.0); |
84 |
} else { |
85 |
nameTextField.frame = CGRectMake(79.0, 13.0, 222.0 - size.width, 24.0); |
86 |
} |
87 |
|
88 |
|
89 |
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { |
90 |
contentTypeTextField = [[UITextField alloc] initWithFrame:CGRectMake(79.0, 13.0, 400.0, 24.0)]; |
91 |
} else { |
92 |
contentTypeTextField = [[UITextField alloc] initWithFrame:CGRectMake(79.0, 13.0, 222.0, 24.0)]; |
93 |
} |
94 |
contentTypeTextField.delegate = self; |
95 |
contentTypeTextField.font = [UIFont systemFontOfSize:17.0]; |
96 |
contentTypeTextField.textColor = [UIColor value1DetailTextLabelColor]; |
97 |
contentTypeTextField.backgroundColor = [UIColor clearColor]; |
98 |
contentTypeTextField.textAlignment = UITextAlignmentRight; |
99 |
contentTypeTextField.returnKeyType = UIReturnKeyDone; |
100 |
contentTypeTextField.autocorrectionType = UITextAutocorrectionTypeNo; |
101 |
contentTypeTextField.autocapitalizationType = UITextAutocapitalizationTypeNone; |
102 |
|
103 |
if (contentTypeEditable) { |
104 |
if (self.contentType) { |
105 |
contentTypeTextField.text = self.contentType; |
106 |
} else { |
107 |
contentTypeTextField.text = [OCMimeType mimeTypeForFileExtension:[self.format substringFromIndex:1]]; |
108 |
} |
109 |
} else { |
110 |
contentTypeTextField.enabled = NO; |
111 |
if (self.contentType) { |
112 |
contentTypeTextField.placeholder = self.contentType; |
113 |
} else { |
114 |
contentTypeTextField.placeholder = [OCMimeType mimeTypeForFileExtension:[self.format substringFromIndex:1]]; |
115 |
} |
116 |
} |
117 |
} |
118 |
|
119 |
#pragma mark - |
120 |
#pragma mark Table view data source |
121 |
|
122 |
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { |
123 |
return 2; |
124 |
} |
125 |
|
126 |
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { |
127 |
if (section == kName) { |
128 |
return 2; |
129 |
} else { |
130 |
return 1; |
131 |
} |
132 |
} |
133 |
|
134 |
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section { |
135 |
if (section == kContentType) { |
136 |
return @"The Content Type (MIME Type) is a universal way to describe content regardless of the file extension."; |
137 |
} else { |
138 |
return @""; |
139 |
} |
140 |
} |
141 |
|
142 |
- (UITableViewCell *)tableView:(UITableView *)tableView textFieldCellForRowAtIndexPath:(NSIndexPath *)indexPath { |
143 |
if (indexPath.section == kName) { |
144 |
static NSString *CellIdentifier = @"NameCell"; |
145 |
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; |
146 |
if (cell == nil) { |
147 |
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease]; |
148 |
cell.selectionStyle = UITableViewCellSelectionStyleNone; |
149 |
cell.textLabel.text = @"Name"; |
150 |
[cell addSubview:nameTextField]; |
151 |
[cell addSubview:formatLabel]; |
152 |
} |
153 |
return cell; |
154 |
} else { |
155 |
static NSString *CellIdentifier = @"ContentTypeCell"; |
156 |
RSTextFieldCell *cell = (RSTextFieldCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; |
157 |
if (cell == nil) { |
158 |
cell = [[[RSTextFieldCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease]; |
159 |
cell.selectionStyle = UITableViewCellSelectionStyleNone; |
160 |
cell.modalPresentationStyle = UIModalPresentationFormSheet; |
161 |
cell.textLabel.text = @"Content Type"; |
162 |
contentTypeTextField = cell.textField; |
163 |
if (contentTypeEditable) { |
164 |
if (self.contentType) { |
165 |
contentTypeTextField.text = self.contentType; |
166 |
} else { |
167 |
contentTypeTextField.text = [OCMimeType mimeTypeForFileExtension:[self.format substringFromIndex:1]]; |
168 |
} |
169 |
} else { |
170 |
contentTypeTextField.enabled = NO; |
171 |
if (self.contentType) { |
172 |
contentTypeTextField.placeholder = self.contentType; |
173 |
} else { |
174 |
contentTypeTextField.placeholder = [OCMimeType mimeTypeForFileExtension:[self.format substringFromIndex:1]]; |
175 |
} |
176 |
} |
177 |
|
178 |
} |
179 |
return cell; |
180 |
} |
181 |
} |
182 |
|
183 |
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { |
184 |
|
185 |
if (indexPath.section == kName && indexPath.row == 0) { |
186 |
return [self tableView:tableView textFieldCellForRowAtIndexPath:indexPath]; |
187 |
} else if (indexPath.section == kContentType) { |
188 |
return [self tableView:tableView textFieldCellForRowAtIndexPath:indexPath]; |
189 |
} else { |
190 |
static NSString *CellIdentifier = @"Cell"; |
191 |
|
192 |
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; |
193 |
if (cell == nil) { |
194 |
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease]; |
195 |
} |
196 |
|
197 |
cell.textLabel.text = @"Size"; |
198 |
cell.detailTextLabel.text = [Container humanizedBytes:[data length]]; |
199 |
cell.selectionStyle = UITableViewCellSelectionStyleNone; |
200 |
cell.accessoryType = UITableViewCellAccessoryNone; |
201 |
|
202 |
return cell; |
203 |
} |
204 |
} |
205 |
|
206 |
#pragma mark - |
207 |
#pragma mark Save Button |
208 |
|
209 |
- (void)saveButtonPressed:(id)sender { |
210 |
[nameTextField resignFirstResponder]; |
211 |
NSString *objectName; |
212 |
if (nameTextField.text && ![nameTextField.text isEqualToString:@""]) { |
213 |
objectName = [NSString stringWithFormat:@"%@%@", nameTextField.text, format]; |
214 |
} else { |
215 |
objectName = [NSString stringWithFormat:@"%@%@", nameTextField.placeholder, format]; |
216 |
} |
217 |
|
218 |
BOOL objectNameHasTrailingSlash = [objectName hasSuffix:@"/"]; |
219 |
NSUInteger indexOfFirstSlash = [objectName rangeOfString:@"/"].location; |
220 |
|
221 |
if (!objectNameHasTrailingSlash && indexOfFirstSlash != NSNotFound || |
222 |
objectNameHasTrailingSlash && indexOfFirstSlash < objectName.length - 1) { |
223 |
[self alert:@"Invalid folder name" message:@"'/' characters are only allowed at the end of folder names"]; |
224 |
return; |
225 |
} |
226 |
|
227 |
if ([folderViewController.folder.objects objectForKey:objectName] && !allowOverwrite) { |
228 |
NSString *alertMessage = [NSString stringWithFormat:@"An object with path '%@' in the container '%@' already exists, do you want to replace it?",objectName, folderViewController.container.name]; |
229 |
NSString *alertTitle = @"Apply changes"; |
230 |
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:alertTitle |
231 |
message:alertMessage |
232 |
delegate:self |
233 |
cancelButtonTitle:@"Cancel" |
234 |
otherButtonTitles:@"OK", nil]; |
235 |
[alert show]; |
236 |
return; |
237 |
} |
238 |
|
239 |
activityIndicatorView = [[ActivityIndicatorView alloc] initWithFrame:[ActivityIndicatorView frameForText:@"Uploading..." withProgress:YES] text:@"Uploading..." withProgress:YES]; |
240 |
[activityIndicatorView addToView:self.view]; |
241 |
|
242 |
StorageObject *object = [[StorageObject alloc] init]; |
243 |
object.name = objectName; |
244 |
object.fullPath = [NSString stringWithFormat:@"%@/%@", [folder fullPath], object.name]; |
245 |
object.fullPath = [object.fullPath substringFromIndex:1]; |
246 |
object.contentType = contentTypeTextField.text; |
247 |
|
248 |
if (!contentType) { |
249 |
object.contentType = @"application/octet-stream"; |
250 |
} |
251 |
|
252 |
object.data = data; |
253 |
object.bytes = [data length]; |
254 |
|
255 |
[self.account.manager writeObject:self.container object:object downloadProgressDelegate:activityIndicatorView.progressView]; |
256 |
|
257 |
successObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"writeObjectSucceeded" object:object queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification* notification) |
258 |
{ |
259 |
[activityIndicatorView removeFromSuperviewAndRelease]; |
260 |
object.data = nil; |
261 |
object.sharing = folder.sharing; |
262 |
[folder.objects setObject:object forKey:object.name]; |
263 |
[folderViewController.tableView reloadData]; |
264 |
allowOverwrite = NO; |
265 |
[self dismissModalViewControllerAnimated:YES]; |
266 |
[[NSNotificationCenter defaultCenter] removeObserver:successObserver]; |
267 |
}]; |
268 |
|
269 |
failureObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"writeObjectFailed" object:object queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification* notification) |
270 |
{ |
271 |
allowOverwrite = NO; |
272 |
[activityIndicatorView removeFromSuperviewAndRelease]; |
273 |
[self alert:@"There was a problem uploading the file." request:[notification.userInfo objectForKey:@"request"]]; |
274 |
[[NSNotificationCenter defaultCenter] removeObserver:failureObserver]; |
275 |
}]; |
276 |
} |
277 |
|
278 |
#pragma mark - Alertview delegate |
279 |
|
280 |
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex |
281 |
{ |
282 |
if (buttonIndex == 1) { |
283 |
allowOverwrite = YES; |
284 |
[self saveButtonPressed:nil]; |
285 |
} |
286 |
} |
287 |
|
288 |
|
289 |
#pragma mark - |
290 |
#pragma mark Text Field Delegate |
291 |
|
292 |
- (BOOL)textFieldShouldReturn:(UITextField *)textField { |
293 |
[textField resignFirstResponder]; |
294 |
return NO; |
295 |
} |
296 |
|
297 |
#pragma mark - |
298 |
#pragma mark Memory management |
299 |
|
300 |
- (void)dealloc { |
301 |
[account release]; |
302 |
[container release]; |
303 |
[folder release]; |
304 |
[folderViewController release]; |
305 |
[data release]; |
306 |
[format release]; |
307 |
[contentType release]; |
308 |
[super dealloc]; |
309 |
} |
310 |
|
311 |
|
312 |
@end |
313 |
|