PageRenderTime 51ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/Classes/TaskViewController.m

https://github.com/intabulas/ipivotal
Objective C | 305 lines | 182 code | 72 blank | 51 comment | 14 complexity | 656293581dcd4af58f185211cb83eed2 MD5 | raw file
  1. //
  2. // Copyright (c) 2008-2011, Mark Lussier
  3. // http://github.com/intabulas/ipivotal
  4. // All rights reserved.
  5. //
  6. // This software is released under the terms of the BSD License.
  7. // http://www.opensource.org/licenses/bsd-license.php
  8. //
  9. // Redistribution and use in source and binary forms, with or without modification,
  10. // are permitted provided that the following conditions are met:
  11. //
  12. // * Redistributions of source code must retain the above copyright notice, this
  13. // list of conditions and the following disclaimer.
  14. // * Redistributions in binary form must reproduce the above copyright notice,
  15. // this list of conditions and the following disclaimer
  16. // in the documentation and/or other materials provided with the distribution.
  17. // * Neither the name of iPivotal nor the names of its contributors may be used
  18. // to endorse or promote products derived from this software without specific
  19. // prior written permission.
  20. //
  21. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  22. // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  23. // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  24. // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  25. // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  26. // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  27. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  28. // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
  29. // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  30. // OF THE POSSIBILITY OF SUCH DAMAGE.
  31. //
  32. #import "TaskViewController.h"
  33. #import "PivotalStory.h"
  34. #import "PivotalProject.h"
  35. #import "PivotalTask.h"
  36. #import "TaskCell.h"
  37. #import "PivotalTaskParserDelegate.h"
  38. @interface TaskViewController ()
  39. - (void)toggleTask:(PivotalTask *)toggleTask;
  40. @end
  41. @implementation TaskViewController
  42. @synthesize taskTableView, story, project;
  43. - (id)initWithProject:(PivotalProject *)theProject andStory:(PivotalStory *)theStory {
  44. [super init];
  45. project = [theProject retain];
  46. story = [theStory retain];
  47. return self;
  48. }
  49. /*
  50. // The designated initializer. Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
  51. - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
  52. if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
  53. // Custom initialization
  54. }
  55. return self;
  56. }
  57. */
  58. - (void)viewDidLoad {
  59. [super viewDidLoad];
  60. // self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCompose target:self action:@selector(composeReply:)];
  61. [self setTitle:kLabelTasks];
  62. }
  63. - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
  64. // Return YES for supported orientations
  65. return YES;
  66. }
  67. - (void)didReceiveMemoryWarning {
  68. // Releases the view if it doesn't have a superview.
  69. [super didReceiveMemoryWarning];
  70. // Release any cached data, images, etc that aren't in use.
  71. }
  72. - (void)viewDidUnload {
  73. [super viewDidUnload];
  74. // Release any retained subviews of the main view.
  75. // e.g. self.myOutlet = nil;
  76. }
  77. - (void)dealloc {
  78. [story release];
  79. [project release];
  80. [taskTableView release];
  81. [super dealloc];
  82. }
  83. #pragma mark Table view methods
  84. - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
  85. return 1;
  86. }
  87. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
  88. return [story.tasks count];
  89. }
  90. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  91. TaskCell *cell = (TaskCell*)[taskTableView dequeueReusableCellWithIdentifier:kIdentifierLabelCell];
  92. if (cell == nil) {
  93. cell = [[[TaskCell alloc] initWithFrame:CGRectZero reuseIdentifier:kIdentifierLabelCell] autorelease];
  94. }
  95. PivotalTask *task = [story.tasks objectAtIndex:indexPath.row];
  96. [cell.description setText:task.description];
  97. [cell toggle:task.complete];
  98. return cell;
  99. }
  100. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
  101. TaskCell *newCell = (TaskCell*)[taskTableView cellForRowAtIndexPath:indexPath];
  102. PivotalTask *task = [story.tasks objectAtIndex:indexPath.row];
  103. task.complete = !task.complete;
  104. [newCell toggle:!newCell.completed];
  105. [self toggleTask:task];
  106. [taskTableView deselectRowAtIndexPath:indexPath animated:YES];
  107. }
  108. #pragma mark Editing
  109. - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
  110. if (editingStyle == UITableViewCellEditingStyleDelete) {
  111. PivotalTask *task = [story.tasks objectAtIndex:indexPath.row];
  112. [self deleteTask:task];
  113. [story.tasks removeObjectAtIndex:indexPath.row];
  114. [self.taskTableView reloadData];
  115. }
  116. }
  117. - (void)deleteTask:(PivotalTask *)deleteTask {
  118. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  119. [self showHUDWithLabel:@"Deleting Task"];
  120. [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
  121. NSString *urlString = [NSString stringWithFormat:kUrlUpdateTask, project.projectId, story.storyId, deleteTask.taskId];
  122. NSURL *followingURL = [NSURL URLWithString:urlString];
  123. ASIHTTPRequest *request = [PivotalResource authenticatedRequestForURL:followingURL];
  124. [request setRequestMethod:@"DELETE"];
  125. [request startSynchronous];
  126. #if LOG_NETWORKWORK
  127. PTLog(@" Response: '%@'", [request responseString]);
  128. #endif
  129. NSError *error = [request error];
  130. [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
  131. [self hideHUD];
  132. if ( error ) {
  133. UIAlertView *alert;
  134. alert = [[UIAlertView alloc] initWithTitle:@"Error Deleting Task" message:@"There was a problem deleting this task. Please try again later" delegate:self cancelButtonTitle:@"okay" otherButtonTitles: nil];
  135. [alert show];
  136. [alert release];
  137. }
  138. [pool release];
  139. }
  140. #pragma mark Add Task
  141. - (IBAction)addTask:(id)sender {
  142. UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Add New Task" message:@"\n" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Add", nil];
  143. newTaskField = [[UITextField alloc] initWithFrame:CGRectMake(12.0, 50.0, 260.0, 25.0)];
  144. [newTaskField setBackgroundColor:[UIColor whiteColor]];
  145. [newTaskField setPlaceholder:@"enter task name"];
  146. [alert addSubview:newTaskField];
  147. [alert show];
  148. [alert release];
  149. [newTaskField becomeFirstResponder];
  150. }
  151. - (void) alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)buttonIndex{
  152. [newTaskField resignFirstResponder];
  153. if (buttonIndex == 1) {
  154. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  155. // [self showHUDWithLabel:kLabelSaving];
  156. [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
  157. NSURL *followingURL = [NSURL URLWithString:[NSString stringWithFormat:kUrlAddTask, project.projectId, story.storyId]];
  158. ASIHTTPRequest *request = [PivotalResource authenticatedRequestForURL:followingURL];
  159. NSString *newProject = [NSString stringWithFormat:kXmlAddTask, newTaskField.text];
  160. [request setRequestMethod:@"POST"];
  161. [request addRequestHeader:kHttpContentType value:kHttpMimeTypeXml];
  162. [request setPostBody:[[[NSMutableData alloc] initWithData:[newProject dataUsingEncoding:NSUTF8StringEncoding]]autorelease]];
  163. [request startSynchronous];
  164. #if LOG_NETWORK
  165. PTLog(@" Response: '%@'", [request responseString]);
  166. #endif
  167. NSError *error = [request error];
  168. [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
  169. if ( error ) {
  170. UIAlertView *alert;
  171. alert = [[UIAlertView alloc] initWithTitle:@"Error Adding Task" message:@"There was a problem adding a task to this story. Please try again later" delegate:self cancelButtonTitle:@"okay" otherButtonTitles: nil];
  172. [alert show];
  173. [alert release];
  174. } else {
  175. PivotalTaskParserDelegate *parserDelegate = [[PivotalTaskParserDelegate alloc] initWithTarget:self andSelector:@selector(loadedTask:)];
  176. NSXMLParser *parser = [[NSXMLParser alloc] initWithData:[request responseData]];
  177. [parser setDelegate:parserDelegate];
  178. [parser setShouldProcessNamespaces:NO];
  179. [parser setShouldReportNamespacePrefixes:NO];
  180. [parser setShouldResolveExternalEntities:NO];
  181. [parser parse];
  182. [parser release];
  183. [parserDelegate release];
  184. }
  185. [pool release];
  186. [self.taskTableView reloadData];
  187. // [self.navigationController popViewControllerAnimated:YES];
  188. }
  189. }
  190. - (void)loadedTask:(id)theResult {
  191. if ([theResult isKindOfClass:[NSError class]]) {
  192. // self.error = theResult;
  193. // self.status = PivotalResourceStatusNotLoaded;
  194. } else {
  195. //self. = theResult;
  196. NSArray *tasks = theResult;
  197. if ( tasks.count > 0 ) {
  198. PivotalTask *tmpTask = [tasks objectAtIndex:0];
  199. [story.tasks addObject:tmpTask];
  200. }
  201. }
  202. }
  203. - (void)toggleTask:(PivotalTask *)toggleTask {
  204. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  205. [self showHUDWithLabel:@"Toggling Task"];
  206. [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
  207. NSString *urlString = [NSString stringWithFormat:kUrlUpdateTask, project.projectId, story.storyId, toggleTask.taskId];
  208. NSURL *followingURL = [NSURL URLWithString:urlString];
  209. NSString *completeState = @"false";
  210. if ( toggleTask.complete ) {
  211. completeState = @"true";
  212. }
  213. NSString *updateTask = [NSString stringWithFormat:kXmlToggleTask, toggleTask.description, completeState];
  214. ASIHTTPRequest *request = [PivotalResource authenticatedRequestForURL:followingURL];
  215. [request setRequestMethod:@"PUT"];
  216. [request addRequestHeader:kHttpContentType value:kHttpMimeTypeXml];
  217. [request setPostBody:[[[NSMutableData alloc] initWithData:[updateTask dataUsingEncoding:NSUTF8StringEncoding]]autorelease]];
  218. [request startSynchronous];
  219. #if LOG_NETWORK
  220. PTLog(@" Response: '%@'", [request responseString]);
  221. #endif
  222. NSError *error = [request error];
  223. [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
  224. [self hideHUD];
  225. if ( error ) {
  226. UIAlertView *alert;
  227. alert = [[UIAlertView alloc] initWithTitle:@"Error Toggling Task" message:@"There was a problem toggling this task. Please try again later" delegate:self cancelButtonTitle:@"okay" otherButtonTitles: nil];
  228. [alert show];
  229. [alert release];
  230. }
  231. [pool release];
  232. }
  233. @end