root / Classes / StorageObjectViewController.m @ 38d59b6c
History | View | Annotate | Download (24.3 kB)
1 |
// |
---|---|
2 |
// StorageObjectViewController.m |
3 |
// OpenStack |
4 |
// |
5 |
// Created by Mike Mayo on 12/19/10. |
6 |
// The OpenStack project is provided under the Apache 2.0 license. |
7 |
// |
8 |
|
9 |
#import "StorageObjectViewController.h" |
10 |
#import "OpenStackAccount.h" |
11 |
#import "Container.h" |
12 |
#import "Folder.h" |
13 |
#import "StorageObject.h" |
14 |
#import "AccountManager.h" |
15 |
#import "AnimatedProgressView.h" |
16 |
#import "UIViewController+Conveniences.h" |
17 |
#import "MediaViewController.h" |
18 |
#import "FolderViewController.h" |
19 |
#import "UIColor+MoreColors.h" |
20 |
#import "OpenStackAppDelegate.h" |
21 |
#import "EditMetadataViewController.h" |
22 |
|
23 |
#define kDetails 0 |
24 |
#define kMetadata 1 |
25 |
|
26 |
#define maxMetadataViewableLength 12 |
27 |
|
28 |
|
29 |
// TODO: use etag to reset download |
30 |
// TODO: try downloading directly to the file to save memory. don't use object.data |
31 |
|
32 |
/* |
33 |
Name whatever.txt |
34 |
Full Path |
35 |
Size 123 KB |
36 |
Content Type text/plain |
37 |
|
38 |
Metadata |
39 |
Key Value -> tap goes to a metadata item VC to edit or delete |
40 |
Key Value |
41 |
Add Metadata... (if max not already reached) |
42 |
|
43 |
CDN URL sections (action sheet to copy, open in safari, and email link) |
44 |
|
45 |
Download File (if downloaded, Open File and Mail File as Attachment) |
46 |
"After you download the file, you'll be able to attempt to open it and mail is as an attachment." |
47 |
|
48 |
Delete Object |
49 |
*/ |
50 |
|
51 |
@implementation StorageObjectViewController |
52 |
|
53 |
@synthesize account, container, folder, object, tableView, folderViewController; |
54 |
|
55 |
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation { |
56 |
return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) || (toInterfaceOrientation == UIInterfaceOrientationPortrait); |
57 |
} |
58 |
|
59 |
- (void)setBackgroundView { |
60 |
|
61 |
UIImageView *logo = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"cloudfiles-large.png"]]; |
62 |
|
63 |
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { |
64 |
UIView *backgroundContainer = [[UIView alloc] init]; |
65 |
backgroundContainer.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; |
66 |
backgroundContainer.backgroundColor = [UIColor iPadTableBackgroundColor]; |
67 |
logo.contentMode = UIViewContentModeScaleAspectFit; |
68 |
logo.frame = CGRectMake(100.0, 100.0, 1000.0, 1000.0); |
69 |
logo.alpha = 0.5; |
70 |
[backgroundContainer addSubview:logo]; |
71 |
tableView.backgroundView = backgroundContainer; |
72 |
[backgroundContainer release]; |
73 |
} else { |
74 |
self.tableView.backgroundView = nil; |
75 |
} |
76 |
[logo release]; |
77 |
} |
78 |
|
79 |
|
80 |
#pragma mark - |
81 |
#pragma mark View lifecycle |
82 |
|
83 |
- (void)viewDidLoad { |
84 |
[super viewDidLoad]; |
85 |
deleteActionSheet = [[UIActionSheet alloc] initWithTitle:@"Are you sure you want to delete this file? This operation cannot be undone." delegate:self cancelButtonTitle:@"Cancel" destructiveButtonTitle:@"Delete File" otherButtonTitles:nil]; |
86 |
} |
87 |
|
88 |
- (void)viewWillAppear:(BOOL)animated { |
89 |
[super viewWillAppear:animated]; |
90 |
self.navigationItem.title = object.name; |
91 |
|
92 |
NSIndexPath* selection = [self.tableView indexPathForSelectedRow]; |
93 |
if (selection) |
94 |
[self.tableView deselectRowAtIndexPath:selection animated:YES]; |
95 |
|
96 |
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); |
97 |
NSString *documentsDirectory = [paths objectAtIndex:0]; |
98 |
NSString *shortPath = [NSString stringWithFormat:@"/%@/%@", self.container.name, self.object.fullPath]; |
99 |
NSString *filePath = [documentsDirectory stringByAppendingString:shortPath]; |
100 |
|
101 |
NSFileManager *fileManager = [NSFileManager defaultManager]; |
102 |
fileDownloaded = [fileManager fileExistsAtPath:filePath]; |
103 |
|
104 |
downloadProgressView = [[AnimatedProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault]; |
105 |
|
106 |
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { |
107 |
CGRect rect = downloadProgressView.frame; |
108 |
rect.size.width = 440.0; |
109 |
downloadProgressView.frame = rect; |
110 |
} |
111 |
|
112 |
[self setBackgroundView]; |
113 |
if (self.container.cdnEnabled) { |
114 |
cdnURLSection = 2; |
115 |
actionsSection = 3; |
116 |
deleteSection = 4; |
117 |
} else { |
118 |
cdnURLSection = -1; |
119 |
actionsSection = 2; |
120 |
deleteSection = 3; |
121 |
} |
122 |
|
123 |
// let's see if we can tweet |
124 |
UIApplication *app = [UIApplication sharedApplication]; |
125 |
NSURL *twitterURL = [NSURL URLWithString:@"twitter://post?message=test"]; |
126 |
|
127 |
if ([app canOpenURL:twitterURL]) { |
128 |
cdnURLActionSheet = [[UIActionSheet alloc] initWithTitle:[[NSString stringWithFormat:@"%@/%@", self.container.cdnURL, self.object.fullPath] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding] delegate:self cancelButtonTitle:@"Cancel" destructiveButtonTitle:nil otherButtonTitles:@"Copy to Pasteboard", @"Open in Safari", @"Email Link to File", @"Tweet Link to File", nil]; |
129 |
} else { |
130 |
cdnURLActionSheet = [[UIActionSheet alloc] initWithTitle:[[NSString stringWithFormat:@"%@/%@", self.container.cdnURL, self.object.fullPath] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding] delegate:self cancelButtonTitle:@"Cancel" destructiveButtonTitle:nil otherButtonTitles:@"Copy to Pasteboard", @"Open in Safari", @"Email Link to File", nil]; |
131 |
} |
132 |
|
133 |
[self.tableView reloadData]; |
134 |
} |
135 |
|
136 |
#pragma mark - |
137 |
#pragma mark Table view data source |
138 |
|
139 |
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { |
140 |
return self.container.cdnEnabled ? 5 : 4; |
141 |
} |
142 |
|
143 |
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { |
144 |
if (section == kDetails) { |
145 |
return 4; |
146 |
} else if (section == kMetadata) { |
147 |
return 1 + [object.metadata count]; |
148 |
} else if (section == cdnURLSection) { |
149 |
return 1; |
150 |
} else if (section == actionsSection) { |
151 |
return fileDownloaded ? 2 : 1; |
152 |
} else if (section == deleteSection) { |
153 |
return 1; |
154 |
} else { |
155 |
return 1; |
156 |
} |
157 |
} |
158 |
|
159 |
/* |
160 |
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section { |
161 |
if (section == actionsSection) { |
162 |
return @"After you download the file, you'll be able to attempt to open it and mail it as an attachment."; |
163 |
} else { |
164 |
return @""; |
165 |
} |
166 |
} |
167 |
*/ |
168 |
|
169 |
- (CGFloat)findLabelHeight:(NSString*)text font:(UIFont *)font { |
170 |
CGSize textLabelSize; |
171 |
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { |
172 |
// 616, 678 |
173 |
textLabelSize = CGSizeMake(596.0, 9000.0f); |
174 |
} else { |
175 |
textLabelSize = CGSizeMake(280.0, 9000.0f); |
176 |
} |
177 |
CGSize stringSize = [text sizeWithFont:font constrainedToSize:textLabelSize lineBreakMode:UILineBreakModeCharacterWrap]; |
178 |
return stringSize.height; |
179 |
} |
180 |
|
181 |
- (CGFloat)tableView:(UITableView *)aTableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { |
182 |
CGFloat result = aTableView.rowHeight; |
183 |
|
184 |
if (indexPath.section == cdnURLSection) { |
185 |
result = 22.0 + [self findLabelHeight:[[NSString stringWithFormat:@"%@/%@", self.container.cdnURL, self.object.fullPath] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding] font:[UIFont systemFontOfSize:18.0]]; |
186 |
} else if (indexPath.section == kDetails && indexPath.row == 1) { |
187 |
CGSize textLabelSize; |
188 |
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { |
189 |
textLabelSize = CGSizeMake(537.0, 9000.0f); |
190 |
} else { |
191 |
textLabelSize = CGSizeMake(221.0, 9000.0f); |
192 |
} |
193 |
CGSize stringSize = [object.fullPath sizeWithFont:[UIFont systemFontOfSize:18.0] constrainedToSize:textLabelSize lineBreakMode:UILineBreakModeWordWrap]; |
194 |
return 22.0 + stringSize.height; |
195 |
} else if (indexPath.section == kDetails && indexPath.row == 0) { |
196 |
CGSize textLabelSize; |
197 |
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { |
198 |
textLabelSize = CGSizeMake(537.0, 9000.0f); |
199 |
} else { |
200 |
textLabelSize = CGSizeMake(221.0, 9000.0f); |
201 |
} |
202 |
CGSize stringSize = [object.name sizeWithFont:[UIFont systemFontOfSize:18.0] constrainedToSize:textLabelSize lineBreakMode:UILineBreakModeWordWrap]; |
203 |
return 22.0 + stringSize.height; |
204 |
} |
205 |
|
206 |
return MAX(aTableView.rowHeight, result); |
207 |
} |
208 |
|
209 |
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { |
210 |
|
211 |
static NSString *CellIdentifier = @"Cell"; |
212 |
|
213 |
UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:CellIdentifier]; |
214 |
if (cell == nil) { |
215 |
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease]; |
216 |
//cell.backgroundColor = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:0.93]; |
217 |
cell.textLabel.backgroundColor = [UIColor clearColor]; |
218 |
cell.detailTextLabel.backgroundColor = [UIColor clearColor]; |
219 |
cell.detailTextLabel.numberOfLines = 0; |
220 |
cell.detailTextLabel.lineBreakMode = UILineBreakModeWordWrap; |
221 |
} |
222 |
|
223 |
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { |
224 |
cell.backgroundColor = [UIColor colorWithRed:1 green:1 blue:1 alpha:0.8]; |
225 |
} |
226 |
|
227 |
cell.detailTextLabel.textAlignment = UITextAlignmentRight; |
228 |
|
229 |
// Configure the cell... |
230 |
if (indexPath.section == kDetails) { |
231 |
cell.accessoryType = UITableViewCellAccessoryNone; |
232 |
cell.selectionStyle = UITableViewCellSelectionStyleNone; |
233 |
cell.accessoryView = nil; |
234 |
if (indexPath.row == 0) { |
235 |
cell.textLabel.text = @"Name"; |
236 |
cell.detailTextLabel.text = object.name; |
237 |
} else if (indexPath.row == 1) { |
238 |
cell.textLabel.text = @"Full Path"; |
239 |
cell.detailTextLabel.text = object.fullPath; |
240 |
} else if (indexPath.row == 2) { |
241 |
cell.textLabel.text = @"Size"; |
242 |
cell.detailTextLabel.text = [object humanizedBytes]; |
243 |
} else if (indexPath.row == 3) { |
244 |
cell.textLabel.text = @"Type"; |
245 |
cell.detailTextLabel.text = object.contentType; |
246 |
} |
247 |
} else if (indexPath.section == kMetadata) { |
248 |
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; |
249 |
cell.selectionStyle = UITableViewCellSelectionStyleBlue; |
250 |
cell.accessoryView = nil; |
251 |
if (indexPath.row == [object.metadata count]) { |
252 |
cell.textLabel.text = @"Add Metadata"; |
253 |
cell.detailTextLabel.text = @""; |
254 |
} else { |
255 |
NSString *key = [[object.metadata allKeys] objectAtIndex:indexPath.row]; |
256 |
NSString *value = [object.metadata objectForKey:key]; |
257 |
NSString *metadataKeyCellText = key; |
258 |
NSString *metadataValueCellText = value; |
259 |
if ([metadataKeyCellText length] > maxMetadataViewableLength) { |
260 |
metadataKeyCellText = [metadataKeyCellText substringToIndex:(maxMetadataViewableLength - 3)]; |
261 |
metadataKeyCellText = [metadataKeyCellText stringByAppendingString:@"..."]; |
262 |
} |
263 |
if ([metadataValueCellText length] > maxMetadataViewableLength) { |
264 |
metadataValueCellText = [metadataValueCellText substringToIndex:(maxMetadataViewableLength - 3)]; |
265 |
metadataValueCellText = [metadataValueCellText stringByAppendingString:@"..."]; |
266 |
} |
267 |
|
268 |
cell.textLabel.text = metadataKeyCellText; |
269 |
cell.detailTextLabel.text = metadataValueCellText; |
270 |
} |
271 |
} else if (indexPath.section == cdnURLSection) { |
272 |
cell.detailTextLabel.textAlignment = UITextAlignmentLeft; |
273 |
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; |
274 |
cell.textLabel.text = @""; |
275 |
cell.detailTextLabel.text = [[NSString stringWithFormat:@"%@/%@", self.container.cdnURL, self.object.fullPath] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; |
276 |
} else if (indexPath.section == actionsSection) { |
277 |
cell.accessoryView = nil; |
278 |
if (performingAction) { |
279 |
cell.textLabel.textColor = [UIColor grayColor]; |
280 |
cell.selectionStyle = UITableViewCellSelectionStyleNone; |
281 |
cell.accessoryType = UITableViewCellAccessoryNone; |
282 |
} else { |
283 |
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; |
284 |
cell.selectionStyle = UITableViewCellSelectionStyleBlue; |
285 |
} |
286 |
|
287 |
if (indexPath.row == 0) { |
288 |
if (fileDownloaded) { |
289 |
cell.textLabel.text = @"Open File"; |
290 |
} else { |
291 |
if (fileDownloading) { |
292 |
cell.accessoryView = downloadProgressView; |
293 |
// TODO: if you leave this view while downloading, there's EXC_BAD_ACCESS |
294 |
cell.textLabel.text = @"Downloading"; |
295 |
} else { |
296 |
cell.textLabel.text = @"Download File"; |
297 |
} |
298 |
} |
299 |
cell.detailTextLabel.text = @""; |
300 |
|
301 |
} else if (indexPath.row == 1) { |
302 |
cell.textLabel.text = @"Email File as Attachment"; |
303 |
cell.detailTextLabel.text = @""; |
304 |
} |
305 |
} else if (indexPath.section == deleteSection) { |
306 |
cell.textLabel.text = @"Delete Object"; |
307 |
cell.detailTextLabel.text = @""; |
308 |
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; |
309 |
cell.selectionStyle = UITableViewCellSelectionStyleBlue; |
310 |
} |
311 |
|
312 |
return cell; |
313 |
} |
314 |
|
315 |
|
316 |
#pragma mark - |
317 |
#pragma mark Table view delegate |
318 |
|
319 |
- (void)reloadActionsTitleRow:(NSTimer *)timer { |
320 |
[[timer.userInfo objectForKey:@"tableView"] reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:0 inSection:actionsSection]] withRowAnimation:UITableViewRowAnimationNone]; |
321 |
} |
322 |
|
323 |
- (void)tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { |
324 |
if (indexPath.section == kMetadata) { |
325 |
EditMetadataViewController *vc = [[EditMetadataViewController alloc] initWithNibName:@"EditMetadataViewController" bundle:nil]; |
326 |
NSString *metadataKey; |
327 |
NSString *metadataValue; |
328 |
|
329 |
if (indexPath.row == [self.object.metadata count]) { |
330 |
metadataKey = @""; |
331 |
metadataValue = @""; |
332 |
vc.deleteEnabled = FALSE; |
333 |
vc.navigationItem.title = @"Add Metadata"; |
334 |
} |
335 |
else { |
336 |
metadataKey = [[self.object.metadata allKeys] objectAtIndex:indexPath.row]; |
337 |
metadataValue = [self.object.metadata objectForKey:metadataKey]; |
338 |
vc.deleteEnabled = YES; |
339 |
vc.navigationItem.title = @"Edit Metadata"; |
340 |
} |
341 |
|
342 |
vc.metadataKey = metadataKey; |
343 |
vc.metadataValue = metadataValue; |
344 |
vc.account = account; |
345 |
vc.container = container; |
346 |
vc.object = object; |
347 |
[self.navigationController pushViewController:vc animated:YES]; |
348 |
[vc release]; |
349 |
} else if (indexPath.section == cdnURLSection) { |
350 |
[cdnURLActionSheet showInView:self.view]; |
351 |
} else if (indexPath.section == actionsSection) { |
352 |
if (indexPath.row == 0) { |
353 |
if (fileDownloaded) { |
354 |
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); |
355 |
NSString *documentsDirectory = [paths objectAtIndex:0]; |
356 |
NSString *shortPath = [NSString stringWithFormat:@"/%@/%@", self.container.name, self.object.fullPath]; |
357 |
NSString *filePath = [documentsDirectory stringByAppendingString:shortPath]; |
358 |
|
359 |
UIDocumentInteractionController *vc = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:filePath]]; |
360 |
vc.delegate = self; |
361 |
|
362 |
if (![vc presentPreviewAnimated:YES]) { |
363 |
|
364 |
if ([self.object isPlayableMedia]) { |
365 |
MediaViewController *vc = [[MediaViewController alloc] initWithNibName:@"MediaViewController" bundle:nil]; |
366 |
vc.container = self.container; |
367 |
vc.object = self.object; |
368 |
[self.navigationController pushViewController:vc animated:YES]; |
369 |
[vc release]; |
370 |
} else { |
371 |
[self alert:@"Error" message:@"This file could not be opened."]; |
372 |
[self.tableView deselectRowAtIndexPath:indexPath animated:YES]; |
373 |
} |
374 |
} |
375 |
|
376 |
[self.tableView deselectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:actionsSection] animated:YES]; |
377 |
|
378 |
} else { |
379 |
if (!fileDownloading) { |
380 |
// download the file |
381 |
fileDownloading = YES; |
382 |
[self.account.manager getObject:self.container object:self.object downloadProgressDelegate:self]; |
383 |
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:0 inSection:actionsSection]] withRowAnimation:UITableViewRowAnimationNone]; |
384 |
} |
385 |
|
386 |
} |
387 |
} else if (indexPath.row == 1) { |
388 |
|
389 |
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); |
390 |
NSString *documentsDirectory = [paths objectAtIndex:0]; |
391 |
NSString *shortPath = @""; |
392 |
|
393 |
if (self.container && [self.container respondsToSelector:@selector(name)] && self.object && [self.object respondsToSelector:@selector(fullPath)]) { |
394 |
shortPath = [NSString stringWithFormat:@"/%@/%@", self.container.name, self.object.fullPath]; |
395 |
} |
396 |
|
397 |
NSString *filePath = [documentsDirectory stringByAppendingString:shortPath]; |
398 |
NSData *data = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:filePath]]; |
399 |
|
400 |
MFMailComposeViewController *vc = [[MFMailComposeViewController alloc] init]; |
401 |
vc.mailComposeDelegate = self; |
402 |
[vc setSubject:self.object.name]; |
403 |
[vc addAttachmentData:data mimeType:self.object.contentType fileName:self.object.name]; |
404 |
[vc setMessageBody:@"" isHTML:NO]; |
405 |
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { |
406 |
vc.modalPresentationStyle = UIModalPresentationPageSheet; |
407 |
} |
408 |
[self presentModalViewController:vc animated:YES]; |
409 |
[vc release]; |
410 |
} |
411 |
} else if (indexPath.section == deleteSection) { |
412 |
[deleteActionSheet showInView:self.view]; |
413 |
} |
414 |
} |
415 |
|
416 |
- (void)setProgress:(float)newProgress { |
417 |
[downloadProgressView setProgress:newProgress animated:YES]; |
418 |
if (newProgress >= 1.0) { |
419 |
fileDownloading = NO; |
420 |
fileDownloaded = YES; |
421 |
|
422 |
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:1 inSection:actionsSection]] withRowAnimation:UITableViewRowAnimationBottom]; |
423 |
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:0 inSection:actionsSection]] withRowAnimation:UITableViewRowAnimationNone]; |
424 |
} |
425 |
} |
426 |
|
427 |
#pragma mark - |
428 |
#pragma mark Document Interation Controller Delegate |
429 |
|
430 |
- (UIViewController *)documentInteractionControllerViewControllerForPreview:(UIDocumentInteractionController *) controller { |
431 |
return self.navigationController; |
432 |
} |
433 |
|
434 |
- (void)documentInteractionControllerDidEndPreview:(UIDocumentInteractionController *)controllers { |
435 |
[self.tableView deselectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:actionsSection] animated:YES]; |
436 |
} |
437 |
|
438 |
#pragma mark - |
439 |
#pragma mark Action Sheet Delegate |
440 |
|
441 |
- (void)deleteObjectRow { |
442 |
[self.folderViewController.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:selectedIndexPath] withRowAnimation:UITableViewRowAnimationLeft]; |
443 |
} |
444 |
|
445 |
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex { |
446 |
if ([actionSheet isEqual:deleteActionSheet]) { |
447 |
if (buttonIndex == 0) { |
448 |
// delete the file and pop out |
449 |
[self showToolbarActivityMessage:@"Deleting file..."]; |
450 |
|
451 |
[self.account.manager deleteObject:self.container object:self.object]; |
452 |
|
453 |
deleteSuccessObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"deleteObjectSucceeded" object:self.object |
454 |
queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification* notification) |
455 |
{ |
456 |
[self hideToolbarActivityMessage]; |
457 |
performingAction = NO; |
458 |
[self.folder.objects removeObjectForKey:self.object.name]; |
459 |
[self.navigationController popViewControllerAnimated:YES]; |
460 |
if ([self.folder.objects count] + [self.folder.folders count] == 0) { |
461 |
[self.folderViewController.tableView reloadData]; |
462 |
} else { |
463 |
[self.folderViewController.tableView selectRowAtIndexPath:selectedIndexPath animated:YES scrollPosition:UITableViewScrollPositionNone]; |
464 |
[NSTimer scheduledTimerWithTimeInterval:0.75 target:self selector:@selector(deleteObjectRow) userInfo:nil repeats:NO]; |
465 |
} |
466 |
[[NSNotificationCenter defaultCenter] removeObserver:deleteSuccessObserver]; |
467 |
}]; |
468 |
|
469 |
deleteFailureObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"deleteObjectFailed" object:self.object |
470 |
queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification* notification) |
471 |
{ |
472 |
[self hideToolbarActivityMessage]; |
473 |
performingAction = NO; |
474 |
[self alert:@"There was a problem deleting this file." request:[notification.userInfo objectForKey:@"request"]]; |
475 |
|
476 |
[[NSNotificationCenter defaultCenter] removeObserver:deleteFailureObserver]; |
477 |
|
478 |
}]; |
479 |
|
480 |
} |
481 |
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:deleteSection]; |
482 |
[self.tableView deselectRowAtIndexPath:indexPath animated:YES]; |
483 |
} else if ([actionSheet isEqual:cdnURLActionSheet]) { |
484 |
NSURL *url = [NSURL URLWithString:[[NSString stringWithFormat:@"%@/%@", self.container.cdnURL, self.object.fullPath] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; |
485 |
|
486 |
if (buttonIndex == 0) { |
487 |
// copy to pasteboard |
488 |
UIPasteboard *pasteboard = [UIPasteboard generalPasteboard]; |
489 |
[pasteboard setString:[url description]]; |
490 |
} else if (buttonIndex == 1) { |
491 |
// open in safari |
492 |
UIApplication *application = [UIApplication sharedApplication]; |
493 |
if ([application canOpenURL:url]) { |
494 |
[application openURL:url]; |
495 |
} else { |
496 |
[self alert:@"Error" message:[NSString stringWithFormat:@"This URL cannot be opened.\n%@", url]]; |
497 |
} |
498 |
} else if (buttonIndex == 2) { |
499 |
// email link to file |
500 |
MFMailComposeViewController *vc = [[MFMailComposeViewController alloc] init]; |
501 |
vc.mailComposeDelegate = self; |
502 |
[vc setSubject:self.object.name]; |
503 |
[vc setMessageBody:[url description] isHTML:NO]; |
504 |
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { |
505 |
vc.modalPresentationStyle = UIModalPresentationPageSheet; |
506 |
} |
507 |
[self presentModalViewController:vc animated:YES]; |
508 |
[vc release]; |
509 |
} else if (buttonIndex == 3) { |
510 |
// tweet link to file |
511 |
UIApplication *app = [UIApplication sharedApplication]; |
512 |
NSURL *twitterURL = [NSURL URLWithString:[NSString stringWithFormat:@"twitter://post?message=%@", [[url description] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]]; |
513 |
if ([app canOpenURL:twitterURL]) { |
514 |
[app openURL:twitterURL]; |
515 |
} |
516 |
} |
517 |
[self.tableView deselectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:cdnURLSection] animated:YES]; |
518 |
} |
519 |
} |
520 |
|
521 |
#pragma mark - |
522 |
#pragma mark Mail Composer Delegate |
523 |
|
524 |
// Dismisses the email composition interface when users tap Cancel or Send. |
525 |
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error { |
526 |
[self dismissModalViewControllerAnimated:YES]; |
527 |
[self.tableView deselectRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:actionsSection] animated:YES]; |
528 |
} |
529 |
|
530 |
#pragma mark - |
531 |
#pragma mark Memory management |
532 |
|
533 |
- (void)dealloc { |
534 |
[account release]; |
535 |
[downloadProgressView release]; |
536 |
[deleteActionSheet release]; |
537 |
[cdnURLActionSheet release]; |
538 |
[tableView release]; |
539 |
[folderViewController release]; |
540 |
[super dealloc]; |
541 |
} |
542 |
|
543 |
|
544 |
@end |
545 |
|