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 |
|