2 // AddPhotoViewController.m
5 // Created by Mike Mayo on 1/5/11.
6 // Copyright 2011 __MyCompanyName__. All rights reserved.
9 #import "AddPhotoViewController.h"
10 #import "UIViewController+Conveniences.h"
11 #import "UIColor+MoreColors.h"
13 #import "ActivityIndicatorView.h"
14 #import "StorageObject.h"
15 #import "OpenStackAccount.h"
16 #import "AccountManager.h"
19 #import "FolderViewController.h"
20 #import "NSObject+Conveniences.h"
24 // give me the option to add a description of the file and the URL - date/time stamped
26 @implementation AddPhotoViewController
28 @synthesize image, account, container, folder, folderViewController, isFromCamera;
30 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
31 return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) || (toInterfaceOrientation == UIInterfaceOrientationPortrait);
35 #pragma mark View lifecycle
39 self.navigationItem.title = @"Add Photo";
43 if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
44 nameTextField = [[UITextField alloc] initWithFrame:CGRectMake(98.0, 13.0, 400.0, 24.0)];
46 nameTextField = [[UITextField alloc] initWithFrame:CGRectMake(79.0, 13.0, 222.0, 24.0)];
48 nameTextField.delegate = self;
49 nameTextField.font = [UIFont systemFontOfSize:17.0];
50 nameTextField.textColor = [UIColor value1DetailTextLabelColor];
51 nameTextField.backgroundColor = [UIColor clearColor];
52 nameTextField.textAlignment = UITextAlignmentRight;
53 nameTextField.returnKeyType = UIReturnKeyDone;
54 nameTextField.autocorrectionType = UITextAutocorrectionTypeNo;
55 nameTextField.autocapitalizationType = UITextAutocapitalizationTypeNone;
56 nameTextField.placeholder = [NSString stringWithFormat:@"ios_upload_%.0f", [[NSDate date] timeIntervalSince1970]];
58 if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
59 formatLabel = [[UILabel alloc] initWithFrame:CGRectMake(41.0, 15.5, 458.0, 18.0)];
61 formatLabel = [[UILabel alloc] initWithFrame:CGRectMake(21.0, 15.5, 280.0, 18.0)];
63 formatLabel.font = [UIFont systemFontOfSize:17.0];
64 formatLabel.textColor = [UIColor value1DetailTextLabelColor];
65 formatLabel.backgroundColor = [UIColor clearColor];
66 formatLabel.textAlignment = UITextAlignmentRight;
67 formatLabel.text = format;
69 slider = [[UISlider alloc] init];
72 // move the text field to make room for the numbers label
73 CGSize size = [formatLabel.text sizeWithFont:formatLabel.font constrainedToSize:CGSizeMake(280.0, 900.0f)];
74 if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
75 nameTextField.frame = CGRectMake(98.0, 13.0, 400.0 - size.width, 24.0);
77 nameTextField.frame = CGRectMake(79.0, 13.0, 222.0 - size.width, 24.0);
82 - (void)viewWillAppear:(BOOL)animated {
83 [super viewWillAppear:animated];
84 // data = UIImageJPEGRepresentation(image, slider.value);
87 // when saving a camera image as a PNG, it ends up rotated. i have no idea why and have
88 // not been able to successfully rotate the image, so we're only allowing JPEG from the
89 // camera for now. not a big deal, since the iPhone 4 camera is making 8 MB PNG files
99 - (void)viewDidAppear:(BOOL)animated {
100 [super viewDidAppear:animated];
102 qualityActivityIndicatorView = [[ActivityIndicatorView alloc] initWithFrame:[ActivityIndicatorView frameForText:@"Calculating size..."] text:@"Calculating size..."];
103 [qualityActivityIndicatorView addToView:self.view];
104 [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(calculateSize) userInfo:nil repeats:NO];
108 #pragma mark Table view data source
110 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
111 if ([format isEqualToString:@".jpg"]) {
113 return isFromCamera ? 1 : 2;
115 return isFromCamera ? 2 : 3;
118 return transitioning ? 3 : 2;
122 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
123 if (section == kName) {
125 } else if (section == formatSection) {
127 } else if (section == qualitySection) {
134 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
135 if (indexPath.section == qualitySection) {
136 return tableView.rowHeight + slider.frame.size.height + 3.0;
138 return tableView.rowHeight;
141 - (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section {
142 if (section == formatSection) {
143 return @"JPEG is a lossy format designed for digital photography. PNG is a lossless format that supports transparency.";
144 } else if (section == qualitySection) {
145 return @"A high quality will produce a better image. A low quality will use less space.";
151 - (UITableViewCell *)tableView:(UITableView *)tableView nameCellForRowAtIndexPath:(NSIndexPath *)indexPath {
152 static NSString *CellIdentifier = @"NameCell";
153 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
155 cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];
156 cell.selectionStyle = UITableViewCellSelectionStyleNone;
157 cell.textLabel.text = @"Name";
158 [cell addSubview:nameTextField];
159 [cell addSubview:formatLabel];
164 - (UITableViewCell *)tableView:(UITableView *)tableView qualityCellForRowAtIndexPath:(NSIndexPath *)indexPath {
165 static NSString *CellIdentifier = @"QualityCell";
167 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
169 cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];
170 cell.selectionStyle = UITableViewCellSelectionStyleNone;
172 UILabel *textLabel = [[UILabel alloc] initWithFrame:CGRectMake(20.0, 13.0, 280.0, 20.0)];
173 if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
174 textLabel.frame = CGRectMake(41.0, 13.0, 458.0, 20.0);
176 textLabel.font = [UIFont boldSystemFontOfSize:17.0];
177 textLabel.text = @"Quality";
178 textLabel.textColor = [UIColor blackColor];
179 textLabel.backgroundColor = [UIColor clearColor];
180 [cell addSubview:textLabel];
183 if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
184 slider.frame = CGRectMake(41.0, 38.0, 458.0, slider.frame.size.height);
186 slider.frame = CGRectMake(20.0, 38.0, 280.0, slider.frame.size.height);
189 [slider addTarget:self action:@selector(sliderMoved:) forControlEvents:UIControlEventValueChanged];
190 [slider addTarget:self action:@selector(sliderFinished:) forControlEvents:UIControlEventTouchUpInside];
192 [cell addSubview:slider];
193 qualityLabel = [[UILabel alloc] initWithFrame:CGRectMake(20.0, 14.0, 280.0, 18.0)];
194 if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
195 qualityLabel.frame = CGRectMake(41.0, 14.0, 458.0, 18.0);
197 qualityLabel.font = [UIFont systemFontOfSize:17.0];
198 qualityLabel.textColor = [UIColor value1DetailTextLabelColor];
199 qualityLabel.backgroundColor = [UIColor clearColor];
200 qualityLabel.textAlignment = UITextAlignmentRight;
201 [cell addSubview:qualityLabel];
204 qualityLabel.text = [NSString stringWithFormat:@"%.0f%%", slider.value * 100];
209 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
211 if (indexPath.section == kName && indexPath.row == 0) {
212 return [self tableView:tableView nameCellForRowAtIndexPath:indexPath];
213 } else if (indexPath.section == qualitySection) {
214 return [self tableView:tableView qualityCellForRowAtIndexPath:indexPath];
216 static NSString *CellIdentifier = @"Cell";
218 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
220 cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];
223 if (indexPath.section == kName) {
224 cell.textLabel.text = @"Size";
225 cell.detailTextLabel.text = [Container humanizedBytes:[data length]];
226 cell.selectionStyle = UITableViewCellSelectionStyleNone;
227 cell.accessoryType = UITableViewCellAccessoryNone;
228 } else if (indexPath.section == formatSection) {
229 cell.selectionStyle = UITableViewCellSelectionStyleBlue;
230 if (indexPath.row == 0) {
231 cell.textLabel.text = @"JPEG";
232 cell.detailTextLabel.text = @"";
233 if ([format isEqualToString:@".jpg"]) {
234 cell.accessoryType = UITableViewCellAccessoryCheckmark;
236 cell.accessoryType = UITableViewCellAccessoryNone;
238 } else if (indexPath.row == 1) {
239 cell.textLabel.text = @"PNG";
240 cell.detailTextLabel.text = @"";
241 if ([format isEqualToString:@".png"]) {
242 cell.accessoryType = UITableViewCellAccessoryCheckmark;
244 cell.accessoryType = UITableViewCellAccessoryNone;
248 cell.textLabel.text = @"Quality";
249 cell.detailTextLabel.text = @"65%";
250 cell.selectionStyle = UITableViewCellSelectionStyleNone;
258 #pragma mark Table view delegate
260 - (void)updateFormat {
264 NSArray *indexPaths = [NSArray arrayWithObjects:[NSIndexPath indexPathForRow:0 inSection:formatSection], [NSIndexPath indexPathForRow:1 inSection:formatSection], nil];
265 [self.tableView reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationNone];
269 if ([format isEqualToString:@".jpg"]) {
270 [self.tableView insertSections:[NSIndexSet indexSetWithIndex:qualitySection] withRowAnimation:UITableViewRowAnimationBottom];
272 [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:qualitySection] withRowAnimation:UITableViewRowAnimationTop];
275 formatLabel.text = format;
276 // move the text field to make room for the numbers label
277 CGSize size = [formatLabel.text sizeWithFont:formatLabel.font constrainedToSize:CGSizeMake(280.0, 900.0f)];
278 nameTextField.frame = CGRectMake(79.0, 13.0, 222.0 - size.width, 24.0);
280 qualityActivityIndicatorView = [[ActivityIndicatorView alloc] initWithFrame:[ActivityIndicatorView frameForText:@"Calculating size..."] text:@"Calculating size..."];
281 [qualityActivityIndicatorView addToView:self.view];
282 [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(calculateSize) userInfo:nil repeats:NO];
286 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
287 if (indexPath.section == formatSection) {
288 if (indexPath.row == 0) {
290 } else { //if (indexPath.row == 1) {
293 // [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
294 [NSTimer scheduledTimerWithTimeInterval:0.35 target:self selector:@selector(updateFormat) userInfo:nil repeats:NO];
299 #pragma mark Text Field Delegate
301 - (BOOL)textFieldShouldReturn:(UITextField *)textField {
302 [textField resignFirstResponder];
309 - (void)calculateSize {
310 if ([format isEqualToString:@".jpg"]) {
312 data = UIImageJPEGRepresentation(image, slider.value);
318 // PNG files from the camera need to be rotated
319 UIImage *rotatedImage = [[UIImage alloc] initWithCGImage:(CGImageRef)image scale:1.0 orientation:UIImageOrientationLeft];
320 data = UIImagePNGRepresentation(rotatedImage);
321 [rotatedImage release];
323 data = UIImagePNGRepresentation(image);
328 [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:1 inSection:kName]] withRowAnimation:UITableViewRowAnimationNone];
329 [qualityActivityIndicatorView removeFromSuperviewAndRelease];
332 - (void)sliderFinished:(id)sender {
333 qualityActivityIndicatorView = [[ActivityIndicatorView alloc] initWithFrame:[ActivityIndicatorView frameForText:@"Calculating size..."] text:@"Calculating size..."];
334 [qualityActivityIndicatorView addToView:self.view];
335 [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(calculateSize) userInfo:nil repeats:NO];
338 - (void)sliderMoved:(id)sender {
339 qualityLabel.text = [NSString stringWithFormat:@"%.0f%%", slider.value * 100];
343 #pragma mark Save Button
345 - (void)saveButtonPressed:(id)sender {
346 activityIndicatorView = [[ActivityIndicatorView alloc] initWithFrame:[ActivityIndicatorView frameForText:@"Uploading..." withProgress:YES] text:@"Uploading..." withProgress:YES];
347 [activityIndicatorView addToView:self.view];
349 StorageObject *object = [[StorageObject alloc] init];
351 if (nameTextField.text && ![nameTextField.text isEqualToString:@""]) {
352 object.name = [NSString stringWithFormat:@"%@%@", nameTextField.text, format];
354 object.name = [NSString stringWithFormat:@"%@%@", nameTextField.placeholder, format];
356 object.fullPath = [NSString stringWithFormat:@"%@/%@", [folder fullPath], object.name];
357 object.fullPath = [object.fullPath substringFromIndex:1];
359 if ([format isEqualToString:@".jpg"]) {
360 object.contentType = @"image/jpeg";
362 object.contentType = @"image/png";
366 object.bytes = [data length];
368 [self.account.manager writeObject:self.container object:object downloadProgressDelegate:activityIndicatorView.progressView];
370 successObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"writeObjectSucceeded" object:object queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification* notification)
372 [activityIndicatorView removeFromSuperviewAndRelease];
374 [folder.objects setObject:object forKey:object.name];
375 [folderViewController.tableView reloadData];
376 [self dismissModalViewControllerAnimated:YES];
377 [[NSNotificationCenter defaultCenter] removeObserver:successObserver];
380 failureObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"writeObjectFailed" object:object queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification* notification)
382 [activityIndicatorView removeFromSuperviewAndRelease];
383 [self alert:@"There was a problem uploading this file." request:[notification.userInfo objectForKey:@"request"]];
384 [[NSNotificationCenter defaultCenter] removeObserver:failureObserver];
389 #pragma mark Memory management
396 [folderViewController release];
397 [nameTextField release];
398 [formatLabel release];