home *** CD-ROM | disk | FTP | other *** search
- /*
- File: PopupInTable.m
-
- Contains: Source code for the Controller of the popup menu button
- used in the "Input" window, see also InputController.m
-
- Written by: Eric Simenel
-
- Created: May 1997
-
- Copyright: (c)1997 by Apple Computer, Inc., all rights reserved.
-
- Change History (most recent first):
-
- You may incorporate this sample code into your applications without
- restriction, though the sample code has been provided "AS IS" and the
- responsibility for its operation is 100% yours. However, what you are
- not permitted to do is to redistribute the source as "DSC Sample Code"
- after having made changes. If you're going to re-distribute the source,
- we require that you make it clear in the source that the code was
- descended from Apple Sample Code, but that you've made changes.
- */
-
- #import "PopupInTable.h"
- #import "ComicsObj.h"
- #import "InputController.h"
-
- @implementation PopupInTable
-
- // private _reset
- - (void)_reset
- {
- pub = nil;
- pubTitle = pubChoice = -1;
- alreadyRemoved = 0;
- }
-
- // private _updateCurrentEditedRowWithPubRemoval
- - (void)_updateCurrentEditedRowWithPubRemoval:(BOOL)removal
- {
- if (removal)
- {
- // the pop up is removed from the super view, so it disappears
- if (!alreadyRemoved) [pub removeFromSuperview];
- alreadyRemoved = 1;
- }
- // and let's update the current edited line
- [[ic inputView] deselectRow:pubTitle];
- [[ic inputView] selectRow:pubTitle byExtendingSelection:NO];
- }
-
- - (id)init
- {
- if (self = [super init])
- [self _reset];
- return self;
- }
-
- - (void)releasePub
- {
- if (pub)
- {
- // first let's make the pop up disappear and update the current edited line
- [self _updateCurrentEditedRowWithPubRemoval:YES];
- // now we can release the pop up itself
- [pub release];
- // and reset our private stuff to prevent confusion later on
- [self _reset];
- }
- }
-
- // the user just selected a menu item, let's see what to do
- - (void)pubSelect:(id)sender
- {
- CTitle *thisTitle = [[ic array] objectAtIndex:pubTitle];
- short mod = 0, choice = [pub indexOfSelectedItem], newFlagT = 0, fl = [thisTitle titleFlags];
- short brands[] = {mskMarvel, mskDC, mskOther};
- short series[] = {mskLong, mskMini};
- short kinds[] = {mskMain, mskDual};
- short states[] = {mskLive, mskDead};
- short grades[] = {mskMint, mskFine, mskGood, mskPoor, mskMiss};
- short types[] = {mskComics, mskLuxe, mskNewForm, mskMagazine};
- short cntnts[] = {mskStory, mskInfo, mskReprint};
- short i, j;
- switch (pubChoice)
- {
- // trivial, we modify the title attributes
- case 3: case 4: case 5: case 6:
- {
- switch (pubChoice)
- {
- case 3: newFlagT = ((fl & mskNotBrand ) | brands[choice]); break;
- case 4: newFlagT = ((fl & mskNotSeries) | series[choice]); break;
- case 5: newFlagT = ((fl & mskNotKind ) | kinds[choice]); break;
- case 6: newFlagT = ((fl & mskNotState ) | states[choice]); break;
- }
- if (newFlagT != fl)
- {
- CTitle *newTitle = [[CTitle alloc] initWithAbb:[thisTitle abb] withTitle:[thisTitle title] withFlag:newFlagT];
- [comicsBase modTitle:thisTitle withNewTitle:newTitle];
- [[ic array] replaceObjectAtIndex:pubTitle withObject:newTitle];
- mod = 1;
- }
- break;
- }
- // use charIshMenu and shortIshMenu to determine what to do, and on what
- case 7: case 8: case 9: case 10: case 11: case 12:
- {
- CIssue *thisIssue, *newIssue;
- NSMenuItem *mi;
- char strDate[10];
- switch (charIshMenu[choice])
- {
- // move the selected issue (curIshArray[pubTitle]) to this edit month (shortIshMenu[choice])
- case 'm':
- #if debug
- NSLog(@"choice m for date %@", [CComics nsStrDate:shortIshMenu[choice]]);
- #endif
- thisIssue = [[thisTitle issues] objectAtIndex:[thisTitle findIssue:[ic curIshArray][pubTitle]]];
- if (shortIshMenu[choice] != [thisIssue editMonth])
- {
- newIssue = [[CIssue alloc] initWithIsh:[thisIssue issueNumber] withEdit:shortIshMenu[choice] withBuy:[thisIssue buyMonth] withFlag:[thisIssue issueFlags]];
- [thisTitle modIssue:thisIssue withNewIssue:newIssue];
- mod = 1;
- [self _updateCurrentEditedRowWithPubRemoval:YES];
- }
- break;
- // select the (shortIshMenu[choice]) issue and put it in curIshArray[pubTitle]
- // only useful when many issues of the same title are published the same month (weekly and bi-weekly)
- // see Action Comics run from 601 to 640 for example
- case 's':
- #if debug
- NSLog(@"choice s for issue %@", [NSString stringWithCString:gnums[shortIshMenu[choice]]]);
- #endif
- for(i=0, j=-1; (j==-1); i++) if (charIshMenu[i] == 'w') j = i;
- mi = [pub itemAtIndex:j];
- strcpy(strDate, [[mi title] cString]);
- strDate[1] = ' ';
- [mi setTitle:[NSString stringWithCString:strDate]];
- mi = [pub itemAtIndex:choice];
- strcpy(strDate, [[mi title] cString]);
- strDate[1] = '>';
- [mi setTitle:[NSString stringWithCString:strDate]];
- charIshMenu[j] = 's';
- charIshMenu[choice] = 'w';
- [ic curIshArray][pubTitle] = shortIshMenu[choice];
-
- [ic setTheBuyMonth:[[[thisTitle issues] objectAtIndex:[thisTitle findIssue:shortIshMenu[choice]]] buyMonth]];
-
- [self _updateCurrentEditedRowWithPubRemoval:YES];
- [[[[ic inputView] window] contentView] addSubview:pub];
- alreadyRemoved = 0;
- break;
- // nothing to do here, this menuitem is just for the user to know which issue we're working upon.
- // it is displayed with a starting ">>"
- case 'w':
- #if debug
- NSLog(@"choice w for issue %@", [NSString stringWithCString:gnums[shortIshMenu[choice]]]);
- #endif
- break;
- // add issue (shortIshMenu[choice])
- // or move it to this edit month (the current column) if it was already existing
- case 'a':
- #if debug
- NSLog(@"choice a for issue %@", [NSString stringWithCString:gnums[shortIshMenu[choice]]]);
- #endif
- if ((j = ([thisTitle findIssue:shortIshMenu[choice]])) == -1)
- {
- newIssue = [[CIssue alloc] initWithIsh:shortIshMenu[choice] withEdit:([ic theEditMonth]-12+pubChoice) withBuy:[ic theBuyMonth] withFlag:defaultFI];
- [thisTitle addIssue:newIssue];
- mod = 1;
- [self _updateCurrentEditedRowWithPubRemoval:YES];
- }
- else
- {
- short newFlagI;
- thisIssue = [[thisTitle issues] objectAtIndex:j];
- newFlagI = ([thisIssue issueFlags] & mskNotGrade) | mskMint;
- newIssue = [[CIssue alloc] initWithIsh:[thisIssue issueNumber] withEdit:([ic theEditMonth]-12+pubChoice) withBuy:[ic theBuyMonth] withFlag:newFlagI];
- [thisTitle modIssue:thisIssue withNewIssue:newIssue];
- mod = 1;
- [self _updateCurrentEditedRowWithPubRemoval:YES];
- }
- break;
- // delete the issue (shortIshMenu[choice]) except if it is the last one.
- // I do this to not to have to test against empty issues array in CTitle or CComics methods all the time
- case 'd':
- #if debug
- NSLog(@"choice d for issue %@", [NSString stringWithCString:gnums[shortIshMenu[choice]]]);
- #endif
- if ([thisTitle nbIssues] > 1)
- {
- thisIssue = [[thisTitle issues] objectAtIndex:[thisTitle findIssue:[ic curIshArray][pubTitle]]];
- [thisTitle deleteIssue:thisIssue];
- mod = 1;
- [ic curIshArray][pubTitle] = [[[thisTitle issues] lastObject] issueNumber];
- [self _updateCurrentEditedRowWithPubRemoval:YES];
- }
- else NSRunAlertPanel(@"Comics", @"You can't delete the last issue. Delete the title instead.", @"OK", nil, nil);
- break;
- // the "Other..." choice, transform the current cell in an editable one, and start the edition
- // we'll get the user input in setObjectValue:forTableColumn:row: of InputController
- case 'o':
- #if debug
- NSLog(@"choice o");
- #endif
- [[[[ic inputView] tableColumns] objectAtIndex:pubChoice] setEditable:YES];
- [self _updateCurrentEditedRowWithPubRemoval:YES];
- [[ic inputView] editColumn:pubChoice row:pubTitle withEvent:nil select:YES];
- break;
- // nothing to do here, "empty" menu item.
- case ' ':
- #if debug
- NSLog(@"choice nothing");
- #endif
- break;
- }
- break;
- }
- // trivial, we modify the issue (from the "Issue" column) attributes
- case 15: case 16: case 17:
- {
- CIssue *thisIssue = [[thisTitle issues] objectAtIndex:[thisTitle findIssue:[ic curIshArray][pubTitle]]];
- short newFlagI = 0, fli = [thisIssue issueFlags];
- switch (pubChoice)
- {
- case 15: newFlagI = ((fli & mskNotGrade) | grades[choice]); break;
- case 16: newFlagI = ((fli & mskNotType ) | types[choice]); break;
- case 17: newFlagI = ((fli & mskNotCntnt) | cntnts[choice]); break;
- }
- if (newFlagI != fli)
- {
- CIssue *newIssue = [[CIssue alloc] initWithIsh:[thisIssue issueNumber] withEdit:[thisIssue editMonth] withBuy:[thisIssue buyMonth] withFlag:newFlagI];
- [thisTitle modIssue:thisIssue withNewIssue:newIssue];
- mod = 1;
- }
- break;
- }
- }
- // let's not forget to signal that the database has changed
- if (mod) [ic contentChanged];
- }
-
- - (void)setUpPopup;
- {
- pubTitle = [[ic inputView] clickedRow];
- // has the user clicked in an "empty" row?
- if (pubTitle >= [[ic array] count]) return;
-
- pubChoice = [[ic inputView] clickedColumn];
- if ((pubChoice > 2) && (pubChoice != 13) && (pubChoice != 14))
- {
- CTitle *thisTitle = [[ic array] objectAtIndex:pubTitle];
- CIssue *thisIssue = nil;
- char miTitle[10];
- short i, j, k, k2, nbMI;
- NSRect aRect;
-
- // get the rectangle of the clicked cell
- aRect = [[ic inputView] frameOfCellAtColumn:pubChoice row:pubTitle];
- // convert it in window coordinates
- aRect = [[[[ic inputView] window] contentView] convertRect:aRect fromView:[ic inputView]];
- // add a little extra width
- aRect.size.width += 28;
- // and create the pop up button there
- pub = [[NSPopUpButton alloc] initWithFrame:aRect pullsDown:NO];
- [pub setFont:((pubChoice >= 7) && (pubChoice <= 12))?[ic fontNonProp]:[ic fontProp]];
- // and set the target and action so that we know when the user is using it
- [pub setTarget:self];
- [pub setAction:@selector(pubSelect:)];
- // and now let's put some menu items in the pop up depending on the clicked column
- if ((pubChoice >= 14) && (pubChoice <= 16))
- thisIssue = [[thisTitle issues] objectAtIndex:[thisTitle findIssue:[ic curIshArray][pubTitle]]];
- switch (pubChoice)
- {
- case 3:
- [pub addItemWithTitle:@"Marvel"];
- [pub addItemWithTitle:@"DC"];
- [pub addItemWithTitle:@"Other"];
- [pub selectItemWithTitle:[thisTitle brand]];
- break;
- case 4:
- [pub addItemWithTitle:@"Long"];
- [pub addItemWithTitle:@"Mini"];
- [pub selectItemWithTitle:[thisTitle series]];
- break;
- case 5:
- [pub addItemWithTitle:@"Main"];
- [pub addItemWithTitle:@"Dual"];
- [pub selectItemWithTitle:[thisTitle kind]];
- break;
- case 6:
- [pub addItemWithTitle:@"Live"];
- [pub addItemWithTitle:@"Dead"];
- [pub selectItemWithTitle:[thisTitle tstate]];
- break;
- case 7: case 8: case 9: case 10: case 11: case 12:
- j = -1;
- i = [ic theEditMonth] - 12 + pubChoice;
- for(k=0; k<5; k++) monthArray[k] = -1;
- nbma = 0; nbMI = 0;
- for(k = [thisTitle nbIssues]-1; (k >= 0) && (j == -1); k--)
- if (([thisIssue = [[thisTitle issues] objectAtIndex:k] editMonth] == i) && !([thisIssue issueFlags] & mskMiss)) j = k;
- if (j != -1)
- {
- [ic setTheBuyMonth:[thisIssue buyMonth]];
- for(k2=j; (k2>=0) && ([thisIssue = [[thisTitle issues] objectAtIndex:k2] editMonth] == i); k2--)
- if (!([thisIssue issueFlags] & mskMiss)) monthArray[nbma++] = [thisIssue issueNumber];
- }
- if (nbma == 0)
- {
- short lastIshP1 = [[[thisTitle issues] lastObject] issueNumber] + 1;
- [pub addItemWithTitle:[NSString stringWithCString:strcat(strcpy(miTitle, " "),gnums[lastIshP1])]];
- charIshMenu[nbMI] = 'a'; shortIshMenu[nbMI++] = lastIshP1;
- [pub addItemWithTitle:@""]; charIshMenu[nbMI++] = ' ';
- for(k=lastIshP1-2; k<lastIshP1; k++) if (k >= 0)
- {
- [pub addItemWithTitle:[NSString stringWithCString:strcat(strcpy(miTitle, " "),gnums[k])]];
- charIshMenu[nbMI] = 'a'; shortIshMenu[nbMI++] = k;
- }
- for(k=lastIshP1+1; k<lastIshP1+6; k++)
- {
- [pub addItemWithTitle:[NSString stringWithCString:strcat(strcpy(miTitle, " "),gnums[k])]];
- charIshMenu[nbMI] = 'a'; shortIshMenu[nbMI++] = k;
- }
- [pub addItemWithTitle:@" "]; charIshMenu[nbMI++] = ' ';
- [pub addItemWithTitle:@"Other..."];
- charIshMenu[nbMI] = 'o'; shortIshMenu[nbMI++] = 0;
- }
- else
- {
- for(k=1; k <= 6; k++)
- {
- strcat(strcpy(miTitle, " "), [CComics cStrDate:[ic theEditMonth]-6+k]);
- [pub addItemWithTitle:[NSString stringWithCString:miTitle]];
- charIshMenu[nbMI] = 'm'; shortIshMenu[nbMI++] = [ic theEditMonth]-6+k;
- }
- [pub addItemWithTitle:@" "]; charIshMenu[nbMI++] = ' ';
- for(k=nbma-1; k>=0; k--)
- {
- strcpy(miTitle, " ");
- strcat(miTitle, gnums[monthArray[k]]);
- miTitle[0] = '>';
- if (k == 0) miTitle[1] = '>';
- [pub addItemWithTitle:[NSString stringWithCString:miTitle]];
- charIshMenu[nbMI] = (k==0)?'w':'s'; shortIshMenu[nbMI++] = monthArray[k];
- }
- [pub addItemWithTitle:@""]; charIshMenu[nbMI++] = ' ';
- for(k=monthArray[nbma-1]-2; k<monthArray[nbma-1]; k++) if (k >= 0)
- {
- [pub addItemWithTitle:[NSString stringWithCString:strcat(strcpy(miTitle, " "),gnums[k])]];
- charIshMenu[nbMI] = 'a'; shortIshMenu[nbMI++] = k;
- }
- for(k=monthArray[0]+1; k<monthArray[0]+6; k++)
- {
- [pub addItemWithTitle:[NSString stringWithCString:strcat(strcpy(miTitle, " "),gnums[k])]];
- charIshMenu[nbMI] = 'a'; shortIshMenu[nbMI++] = k;
- }
- [pub addItemWithTitle:@" "]; charIshMenu[nbMI++] = ' ';
- [pub addItemWithTitle:@"Delete"];
- [ic curIshArray][pubTitle] = monthArray[0];
- charIshMenu[nbMI] = 'd'; shortIshMenu[nbMI++] = [ic curIshArray][pubTitle];
- [self _updateCurrentEditedRowWithPubRemoval:NO];
- [pub addItemWithTitle:@" "]; charIshMenu[nbMI++] = ' ';
- [pub addItemWithTitle:@"Other..."];
- charIshMenu[nbMI] = 'o'; shortIshMenu[nbMI++] = 0;
- }
- break;
- case 15:
- [pub addItemWithTitle:@"Mint"];
- [pub addItemWithTitle:@"Fine"];
- [pub addItemWithTitle:@"Good"];
- [pub addItemWithTitle:@"Poor"];
- [pub addItemWithTitle:@"Missing"];
- [pub selectItemWithTitle:[thisIssue grade]];
- break;
- case 16:
- [pub addItemWithTitle:@"Comics"];
- [pub addItemWithTitle:@"Luxe"];
- [pub addItemWithTitle:@"New Format"];
- [pub addItemWithTitle:@"Magazine"];
- [pub selectItemWithTitle:[thisIssue ishtype]];
- break;
- case 17:
- [pub addItemWithTitle:@"Story"];
- [pub addItemWithTitle:@"Info"];
- [pub addItemWithTitle:@"Reprint"];
- [pub selectItemWithTitle:[thisIssue content]];
- break;
- }
- // finally add the pop up button to the content view of the window
- [[[[ic inputView] window] contentView] addSubview:pub];
- // and remember it's here
- alreadyRemoved = 0;
- }
- }
-
- @end
-