CatNiP prefinal
Sähköinen nuottikirja, HY-TKTKL-OHTUPROJ KESÄ11
|
00001 00009 #define LIBRARYTYPE self.master.libraryType.selectedSegmentIndex 00010 00011 #import "ScorePopoverController.h" 00012 #import "CatNiPViewController.h" 00013 00014 @implementation ScorePopoverController 00015 00016 @synthesize compositionData; 00017 @synthesize composition; 00018 @synthesize composer; 00019 @synthesize master; 00020 @synthesize editable; 00021 00029 - (id)initWithStyle:(UITableViewStyle)style masterController:(CatNiPViewController *)controller compositionData:(CompositionData *)compData editable:(BOOL)ed 00030 { 00031 self = [super initWithStyle:style]; 00032 if (self) 00033 { 00034 self.master = controller; 00035 self.composition = compData.compositionName; 00036 self.composer = compData.composerName; 00037 self.compositionData = compData; 00038 self.editable = ed; 00039 } 00040 return self; 00041 } 00042 00043 - (void)dealloc 00044 { 00045 [compositionData release]; 00046 [composition release]; 00047 [composer release]; 00048 [super dealloc]; 00049 } 00050 00051 - (void)didReceiveMemoryWarning 00052 { 00053 // Releases the view if it doesn't have a superview. 00054 [super didReceiveMemoryWarning]; 00055 00056 // Release any cached data, images, etc that aren't in use. 00057 } 00058 00059 #pragma mark - View lifecycle 00060 00061 - (void)viewDidLoad 00062 { 00063 [super viewDidLoad]; 00064 00065 self.tableView.allowsSelectionDuringEditing = YES; 00066 self.tableView.delegate = self; 00067 self.tableView.dataSource = self; 00068 [self.tableView setClipsToBounds:YES]; 00069 00070 // Uncomment the following line to preserve selection between presentations. 00071 // self.clearsSelectionOnViewWillAppear = NO; 00072 00073 // Uncomment the following line to display an Edit button in the navigation bar for this view controller. 00074 // self.navigationItem.rightBarButtonItem = self.editButtonItem; 00075 } 00076 00077 - (void)viewDidUnload 00078 { 00079 [super viewDidUnload]; 00080 // Release any retained subviews of the main view. 00081 // e.g. self.myOutlet = nil; 00082 } 00083 00084 - (void)viewWillAppear:(BOOL)animated 00085 { 00086 [super viewWillAppear:animated]; 00087 } 00088 00089 - (void)viewDidAppear:(BOOL)animated 00090 { 00091 [super viewDidAppear:animated]; 00092 } 00093 00094 - (void)viewWillDisappear:(BOOL)animated 00095 { 00096 [super viewWillDisappear:animated]; 00097 } 00098 00099 - (void)viewDidDisappear:(BOOL)animated 00100 { 00101 [super viewDidDisappear:animated]; 00102 } 00103 00104 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 00105 { 00106 // Return YES for supported orientations 00107 return YES; 00108 } 00109 00110 #pragma mark - Table view data source 00111 /*********** UITableViewDataSource protocol's functions *************/ 00112 /* */ 00113 /* */ 00114 /* For more information about these check framework's API. */ 00115 /********************************************************************/ 00116 00124 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 00125 { 00126 return 1; 00127 } 00128 00129 00136 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 00137 { 00138 return [self.compositionData.musicScores count]; 00139 } 00140 00147 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 00148 { 00149 UITableViewCell *cell = [master tableView:self.tableView createCellWithIdentifier:@"ScoreCell"]; 00150 00151 // make accessory views for both states though only one is used depending on master's 00152 // tableviews' delegates and datasources 00153 cell.editingAccessoryView = [self createAccessoryViewForIndexPath:indexPath]; 00154 cell.accessoryView = [self createAccessoryViewForIndexPath:indexPath]; 00155 00156 // adjust background colors to match application "style" 00157 cell.backgroundColor = [UIColor clearColor]; 00158 cell.textLabel.backgroundColor = [self.master.libraryTableViewRight.backgroundColor colorWithAlphaComponent:0.3]; 00159 UIView *bg = [[UIView alloc] init]; 00160 bg.backgroundColor = [self.master.libraryTableViewRight.backgroundColor colorWithAlphaComponent:0.3]; 00161 cell.backgroundView = bg; 00162 00163 /* insert right score name in here */ 00164 NSString *cellText; 00165 cellText = [[self.compositionData.musicScores objectAtIndex:[indexPath row]] description]; 00166 cell.textLabel.text = cellText; 00167 00168 return cell; 00169 } 00170 00177 - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath 00178 { 00179 return self.editable; 00180 } 00181 00192 - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 00193 { 00194 LocalScoreData *selectedScore = [[self.compositionData musicScores] objectAtIndex:indexPath.row]; 00195 00196 if (selectedScore == self.master.currentScore) // can't delete currently showing score 00197 { 00198 UIAlertView *a = [[[UIAlertView alloc] initWithTitle:@"Operation can't be completed" message:@"Score that is currently showing can't be deleted" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] autorelease]; 00199 [a show]; 00200 } 00201 else // remove references to score from local data 00202 { 00203 // if selected score is in currently viewed playlist stop viewing playlist. 00204 if ([LocalDataHandler scoreArray:self.master.currentPlaylist.scorelist hasScoreWithPdfFilePath:selectedScore.pdf]) 00205 { 00206 self.master.currentPlaylist = nil; 00207 } 00208 00209 NSLog(@"musicScores count %d", [[self.compositionData musicScores] count]); 00210 [[self.compositionData musicScores] removeObjectAtIndex:indexPath.row]; 00211 [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationTop]; 00212 NSLog(@"musicScores count %d", [[self.compositionData musicScores] count]); 00213 [self.tableView reloadData]; 00214 00215 00216 [LocalDataHandler removeAndDeleteLocalScoreData:selectedScore fromScoreArray:self.master.localDelegateAndDataSource.allLocalScores andDictionary:self.master.localDelegateAndDataSource.composerDictionary andPlaylistArray:self.master.playlistsDelegateAndDataSource.playlists]; 00217 if ([[self.compositionData musicScores] count] == 0) 00218 { 00219 [self.master dismissScorePopover]; 00220 [self.master.localDelegateAndDataSource updateTables]; 00221 } 00222 } 00223 } 00224 00225 #pragma mark - Table view delegate 00226 /************ UITableViewDelegate protocol's functions **************/ 00227 /* */ 00228 /* */ 00229 /* For more information about these check framework's API. */ 00230 /********************************************************************/ 00231 00242 - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section 00243 { 00244 UILabel *header; 00245 NSString *headerText; 00246 00247 /* switch case for later implementation of different score "types" in different sections, etc. */ 00248 switch (section) { 00249 default: 00250 header = [[[UILabel alloc] initWithFrame:CGRectZero] autorelease]; 00251 headerText = [@"Scores for " stringByAppendingString:self.composition]; 00252 header.text = headerText; 00253 00254 /* define header appearance */ 00255 header.minimumFontSize = 20; 00256 header.textAlignment = UITextAlignmentCenter; 00257 header.numberOfLines = 0; 00258 header.font = [UIFont fontWithName:@"Georgia" size:20.0]; 00259 header.lineBreakMode = UILineBreakModeWordWrap; 00260 00261 /* lighten the color from master.libraryTableViewRight to get UI lighten higher the popups, etc. are. */ 00262 header.backgroundColor = [self.master.libraryTableViewRight.backgroundColor colorWithAlphaComponent:0.40]; 00263 00264 break; 00265 } 00266 return header; 00267 } 00268 00280 - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section 00281 { 00282 NSInteger l = [self.composition length] +10; 00283 return ((int)(l / 45) +1) * 25 + 50; 00284 } 00285 00294 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 00295 { 00296 NSInteger l = [[[[self.compositionData musicScores] objectAtIndex:indexPath.row] description] length] + 3; 00297 NSInteger height = (((int)(l / 50)+1) * 17) + 50; // TODO: refactor this 00298 if (height > 70) return height; 00299 else return 70; 00300 } 00301 00311 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 00312 { 00313 ScoreData *selectedScore= [self.compositionData.musicScores objectAtIndex:[indexPath row]]; 00314 00315 switch (LIBRARYTYPE) 00316 { 00317 case LOCAL: // its already stored locally 00318 [self.master showScoreSheets:(LocalScoreData *)selectedScore]; 00319 break; 00320 case IMSLP: 00321 // already downloading, do nothing 00322 if ([IMSLPQueryHelper readInProgressFor:selectedScore.pdf]) break; 00323 00324 // previously downloaded, don't allow downloading 00325 if ([LocalDataHandler scoreArray:self.master.localDelegateAndDataSource.allLocalScores hasScoreWithPdfFileName:selectedScore.pdf]) break; // 00326 00327 // need to download it first 00328 [IMSLPQueryHelper readIMSLPFile:selectedScore.pdf ofComposition:self.compositionData reportTo:self.master withMethod: 00329 @selector(saveAndShowScore::)]; 00330 UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath]; 00331 cell.editingAccessoryView = [self downloadingAccessoryViewForIndexPath: indexPath]; 00332 cell.accessoryView = [self downloadingAccessoryViewForIndexPath: indexPath]; 00333 break; 00334 default: 00335 // handle exceptions 00336 break; 00337 } 00338 } 00339 00346 - (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath 00347 { 00348 if (self.editable == YES) return UITableViewCellEditingStyleDelete; 00349 return UITableViewCellEditingStyleNone; 00350 } 00351 00359 - (UIView *)createAccessoryViewForIndexPath:(NSIndexPath *)indexPath 00360 { 00361 switch (LIBRARYTYPE) 00362 { 00363 case IMSLP: 00364 return [self IMSLPAccessoryViewForIndexPath:indexPath]; 00365 case LOCAL: 00366 return [self LocalAccessoryViewForIndexPath:indexPath]; 00367 default: 00368 return NULL; 00369 } 00370 } 00371 00382 -(UIView *)IMSLPAccessoryViewForIndexPath:(NSIndexPath *)indexPath 00383 { 00384 ScoreData *selectedScore = [self.compositionData.musicScores objectAtIndex:indexPath.row]; 00385 00386 // pdf associated with selected score is already stored locally. dont allow downloading. 00387 if ([LocalDataHandler scoreArray:self.master.localDelegateAndDataSource.allLocalScores hasScoreWithPdfFileName:selectedScore.pdf]) 00388 { 00389 return [self downloadedAccessoryViewForIndexPath:indexPath]; 00390 } 00391 // pdf associated with seleted score is already downloading. Show progressbar and cancel button. 00392 else if ([IMSLPQueryHelper readInProgressFor:selectedScore.pdf]) 00393 { 00394 return [self downloadingAccessoryViewForIndexPath:indexPath]; 00395 } 00396 // pdf associated with selected score can be downloaded 00397 else 00398 { 00399 return [self downloadableAccessoryViewForIndexPath:indexPath]; 00400 } 00401 } 00402 00410 -(UIView *)LocalAccessoryViewForIndexPath:(NSIndexPath *)indexPath 00411 { 00412 ScoreData *selectedScore = [self.compositionData.musicScores objectAtIndex:indexPath.row]; 00413 ScoreListButton *detailButton = [self createDetailButtonForScore:selectedScore]; 00414 ScoreListButton *playlistButton = [self createAddToPlaylistButtonForScore:selectedScore]; 00415 00416 CGRect frame = CGRectMake(5, 5, 66, 66); 00417 playlistButton.frame = frame; 00418 frame.origin.x = frame.origin.x + 66; 00419 detailButton.frame = frame; 00420 00421 UIView *av = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 143, 76)] autorelease]; 00422 [av addSubview:detailButton]; 00423 [av addSubview:playlistButton]; 00424 return av; 00425 } 00426 00434 -(UIView *)downloadableAccessoryViewForIndexPath:(NSIndexPath *)indexPath 00435 { 00436 UIView *av = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 143, 76)] autorelease]; 00437 ScoreData *selectedScore = [self.compositionData.musicScores objectAtIndex:indexPath.row]; 00438 00439 CGRect frame = CGRectMake(5, 5, 66, 66); 00440 ScoreListButton *downloadButton = [self createDownloadButtonForScore:selectedScore]; 00441 downloadButton.frame = frame; 00442 00443 frame.origin.x = frame.origin.x + 66; 00444 ScoreListButton *detailButton = [self createDetailButtonForScore:selectedScore]; 00445 detailButton.frame = frame; 00446 00447 [av addSubview:downloadButton]; 00448 [av addSubview:detailButton]; 00449 00450 return av; 00451 } 00452 00460 -(UIView *)downloadingAccessoryViewForIndexPath:(NSIndexPath *)indexPath 00461 { 00462 UIView *av = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 76)] autorelease]; 00463 ScoreData *selectedScore = [self.compositionData.musicScores objectAtIndex:indexPath.row]; 00464 00465 CGRect frame = CGRectMake(5, (av.frame.size.height / 2) -3, 57, av.frame.size.height); 00466 00467 // create progressbar for download 00468 UIProgressView *pv = [[[UIProgressView alloc] initWithFrame:frame] autorelease]; 00469 00470 // create timer to update progressbar's view 00471 NSTimer *nt = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(updateProgressView:) userInfo:[[[NSArray alloc] initWithObjects:pv, selectedScore.pdf, nil] retain] repeats:YES]; 00472 [nt retain]; 00473 00474 frame = CGRectMake(frame.origin.x + 57 + 21, 26, 24, 24); 00475 ScoreListButton *cancelButton = [self createCancelButtonForScore:selectedScore]; 00476 cancelButton.frame = frame; 00477 00478 frame.origin.x = frame.origin.x + 66; 00479 ScoreListButton *detailButton = [self createDetailButtonForScore:selectedScore]; 00480 detailButton.frame = frame; 00481 00482 [av addSubview:pv]; 00483 [av addSubview:cancelButton]; 00484 [av addSubview:detailButton]; 00485 00486 return av; 00487 } 00488 00496 -(UIView *)downloadedAccessoryViewForIndexPath:(NSIndexPath *)indexPath 00497 { 00498 UIView *av = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 143, 76)] autorelease]; 00499 ScoreData *selectedScore = [self.compositionData.musicScores objectAtIndex:indexPath.row]; 00500 00501 CGRect frame = CGRectMake(26, 26, 24, 24); 00502 UIImageView *iv = [[[UIImageView alloc] initWithImage:[UIImage imageWithContentsOfFile:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"117-todo.png"]]] autorelease]; 00503 iv.frame = frame; 00504 00505 00506 frame.origin.x = frame.origin.x + 66; 00507 ScoreListButton *detailButton = [self createDetailButtonForScore:selectedScore]; 00508 detailButton.frame = frame; 00509 00510 [av addSubview:iv]; 00511 [av addSubview:detailButton]; 00512 00513 return av; 00514 } 00515 00517 -(ScoreListButton *)createDetailButtonForScore:(ScoreData *)score 00518 { 00519 ScoreListButton *button = [[[ScoreListButton alloc] initWithScore:score] autorelease]; 00520 [button setImage:[UIImage imageWithContentsOfFile:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"06-magnify.png"]] forState:UIControlStateNormal]; 00521 [button setImage:[UIImage imageWithContentsOfFile:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"06-magnify.png"]] forState:UIControlStateSelected]; 00522 [button setShowsTouchWhenHighlighted:YES]; 00523 [button addTarget:self action:@selector(showDetailsForScore:) forControlEvents:UIControlEventTouchUpInside]; 00524 00525 return button; 00526 } 00527 00529 -(ScoreListButton *)createDownloadButtonForScore:(ScoreData *)score 00530 { 00531 ScoreListButton *button = [[[ScoreListButton alloc] initWithScore:score] autorelease]; 00532 [button setImage:[UIImage imageWithContentsOfFile:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"57-download.png"]] forState:UIControlStateNormal]; 00533 [button setImage:[UIImage imageWithContentsOfFile:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"57-download.png"]] forState:UIControlStateSelected]; 00534 [button setShowsTouchWhenHighlighted:YES]; 00535 [button addTarget:self action:@selector(downloadScore:) forControlEvents:UIControlEventTouchUpInside]; 00536 00537 return button; 00538 } 00539 00541 -(ScoreListButton *)createAddToPlaylistButtonForScore:(ScoreData *)score 00542 { 00543 ScoreListButton *button = [[[ScoreListButton alloc] initWithScore:score] autorelease]; 00544 [button setImage:[UIImage imageWithContentsOfFile:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"104-index-cards.png"]] forState:UIControlStateNormal]; 00545 [button setImage:[UIImage imageWithContentsOfFile:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"104-index-cards.png"]] forState:UIControlStateSelected]; 00546 [button setShowsTouchWhenHighlighted:YES]; 00547 [button addTarget:self action:@selector(addToPlaylist:) forControlEvents:UIControlEventTouchUpInside]; 00548 00549 return button; 00550 } 00551 00553 -(ScoreListButton *)createCancelButtonForScore:(ScoreData *)score 00554 { 00555 ScoreListButton *button = [[[ScoreListButton alloc] initWithScore:score] autorelease]; 00556 [button setImage:[UIImage imageWithContentsOfFile:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"cancel.png"]] forState:UIControlStateNormal]; 00557 [button setImage:[UIImage imageWithContentsOfFile:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"cancel.png"]] forState:UIControlStateSelected]; 00558 [button setShowsTouchWhenHighlighted:YES]; 00559 [button addTarget:self action:@selector(cancelDownload:) forControlEvents:UIControlEventTouchUpInside]; 00560 00561 return button; 00562 } 00563 00568 -(void)downloadScore:(id)button 00569 { 00570 if ([button isKindOfClass:[ScoreListButton class]]) // sender is right type! 00571 { 00572 ScoreListButton *b = button; 00573 [IMSLPQueryHelper readIMSLPFile:b.score.pdf ofComposition:self.compositionData reportTo:self.master withMethod:@selector(saveScore::)]; 00574 if ([b.superview.superview isKindOfClass:UITableViewCell.class]) 00575 { 00576 UITableViewCell *cell = (UITableViewCell *)b.superview.superview; 00577 NSIndexPath *ip = [self.tableView indexPathForCell:cell]; 00578 NSLog (@"section: %d, row:%d", [ip section], [ip row]); 00579 00580 // update accessoryview 00581 cell.accessoryView = [self IMSLPAccessoryViewForIndexPath:ip]; 00582 cell.editingAccessoryView = [self IMSLPAccessoryViewForIndexPath:ip]; 00583 00584 } 00585 } 00586 else 00587 { 00588 // sender was wrong type. handle exceptions 00589 return; 00590 } 00591 } 00592 00597 -(void)showDetailsForScore:(id)button 00598 { 00599 if ([button isKindOfClass:[ScoreListButton class]]) // sender is right type! 00600 { 00601 ScoreListButton *b = button; 00602 00603 [self.master openDetailPopoverFromRect:b.frame inView:b.superview withScore:b.score ofComposer:self.composer andComposition:self.composition]; } 00604 else 00605 { 00606 // sender was wrong type. handle exceptions 00607 return; 00608 } 00609 } 00610 00616 -(void)addToPlaylist:(id)button 00617 { 00618 // open playlist popover 00619 if ([button isKindOfClass:[ScoreListButton class]]) // sender is right type! 00620 { 00621 ScoreListButton *b = button; 00622 00623 [self.master openPlaylistPopoverFromRect:b.frame inView:b.superview withScore:(LocalScoreData *)b.score]; 00624 } 00625 else 00626 { 00627 // sender was wrong type. handle exceptions 00628 return; 00629 } 00630 } 00631 00638 -(void)cancelDownload:(id)button 00639 { 00640 if ([button isKindOfClass:[ScoreListButton class]]) // sender is right type! 00641 { 00642 ScoreListButton *b = button; 00643 00644 [IMSLPQueryHelper abortRead:b.score.pdf]; 00645 00646 if ([b.superview.superview isKindOfClass:UITableViewCell.class]) 00647 { 00648 UITableViewCell *cell = (UITableViewCell *)b.superview.superview; 00649 NSIndexPath *ip = [self.tableView indexPathForCell:cell]; 00650 cell.accessoryView = [self IMSLPAccessoryViewForIndexPath:ip]; 00651 cell.editingAccessoryView = [self IMSLPAccessoryViewForIndexPath:ip]; 00652 } 00653 } 00654 else 00655 { 00656 // sender was wrong type. handle exceptions 00657 return; 00658 } 00659 00660 00661 } 00662 00671 -(void)updateProgressView:(NSTimer *)nt; 00672 { 00673 UIProgressView *pv = [(NSArray *)[nt userInfo] objectAtIndex:0]; 00674 NSString *pdf = [(NSArray *)[nt userInfo] objectAtIndex:1]; 00675 pv.progress = [IMSLPQueryHelper downloadProgressFor:pdf]; 00676 [pv.superview setNeedsDisplay]; 00677 00678 if (pv.progress == 1) [nt invalidate]; 00679 } 00680 00681 @end