home *** CD-ROM | disk | FTP | other *** search
/ Big Green CD 8 / BGCD_8_Dev.iso / OPENSTEP / Utilities / Comics-1.0-MIS / PopupInTable.m < prev    next >
Encoding:
Text File  |  1997-09-25  |  18.4 KB  |  399 lines

  1. /*
  2.  File:       PopupInTable.m
  3.  
  4.  Contains:   Source code for the Controller of the popup menu button
  5.              used in the "Input" window, see also InputController.m
  6.  
  7.  Written by: Eric Simenel
  8.  
  9.  Created:    May 1997
  10.  
  11.  Copyright:  (c)1997 by Apple Computer, Inc., all rights reserved.
  12.  
  13.  Change History (most recent first):
  14.  
  15.  You may incorporate this sample code into your applications without
  16.  restriction, though the sample code has been provided "AS IS" and the
  17.  responsibility for its operation is 100% yours.  However, what you are
  18.  not permitted to do is to redistribute the source as "DSC Sample Code"
  19.  after having made changes. If you're going to re-distribute the source,
  20.  we require that you make it clear in the source that the code was
  21.  descended from Apple Sample Code, but that you've made changes.
  22. */
  23.  
  24. #import "PopupInTable.h"
  25. #import "ComicsObj.h"
  26. #import "InputController.h"
  27.  
  28. @implementation PopupInTable
  29.  
  30. // private _reset
  31. - (void)_reset
  32. {
  33.     pub = nil;
  34.     pubTitle = pubChoice = -1;
  35.     alreadyRemoved = 0;
  36. }
  37.  
  38. // private _updateCurrentEditedRowWithPubRemoval
  39. - (void)_updateCurrentEditedRowWithPubRemoval:(BOOL)removal
  40. {
  41.     if (removal)
  42.       {
  43.         // the pop up is removed from the super view, so it disappears
  44.         if (!alreadyRemoved) [pub removeFromSuperview];
  45.         alreadyRemoved = 1;
  46.       }
  47.     // and let's update the current edited line
  48.     [[ic inputView] deselectRow:pubTitle];
  49.     [[ic inputView] selectRow:pubTitle byExtendingSelection:NO];
  50. }
  51.  
  52. - (id)init
  53. {
  54.     if (self = [super init])
  55.         [self _reset];
  56.     return self;
  57. }
  58.  
  59. - (void)releasePub
  60. {
  61.     if (pub)
  62.       {
  63.         // first let's make the pop up disappear and update the current edited line
  64.         [self _updateCurrentEditedRowWithPubRemoval:YES];
  65.         // now we can release the pop up itself
  66.         [pub release];
  67.         // and reset our private stuff to prevent confusion later on
  68.         [self _reset];
  69.       }
  70. }
  71.  
  72. // the user just selected a menu item, let's see what to do
  73. - (void)pubSelect:(id)sender
  74. {
  75.     CTitle *thisTitle = [[ic array] objectAtIndex:pubTitle];
  76.     short mod = 0, choice = [pub indexOfSelectedItem], newFlagT = 0, fl = [thisTitle titleFlags];
  77.     short brands[] = {mskMarvel, mskDC, mskOther};
  78.     short series[] = {mskLong, mskMini};
  79.     short kinds[]  = {mskMain, mskDual};
  80.     short states[] = {mskLive, mskDead};
  81.     short grades[] = {mskMint, mskFine, mskGood, mskPoor, mskMiss};
  82.     short types[]  = {mskComics, mskLuxe, mskNewForm, mskMagazine};
  83.     short cntnts[] = {mskStory, mskInfo, mskReprint};
  84.     short i, j;
  85.     switch (pubChoice)
  86.       {
  87.         // trivial, we modify the title attributes
  88.         case 3: case 4: case 5: case 6:
  89.           {
  90.               switch (pubChoice)
  91.                 {
  92.                   case 3: newFlagT = ((fl & mskNotBrand ) | brands[choice]); break;
  93.                   case 4: newFlagT = ((fl & mskNotSeries) | series[choice]); break;
  94.                   case 5: newFlagT = ((fl & mskNotKind  ) | kinds[choice]); break;
  95.                   case 6: newFlagT = ((fl & mskNotState ) | states[choice]); break;
  96.                 }
  97.               if (newFlagT != fl)
  98.                 {
  99.                   CTitle *newTitle = [[CTitle alloc] initWithAbb:[thisTitle abb] withTitle:[thisTitle title] withFlag:newFlagT];
  100.                   [comicsBase modTitle:thisTitle withNewTitle:newTitle];
  101.                   [[ic array] replaceObjectAtIndex:pubTitle withObject:newTitle];
  102.                   mod = 1;
  103.                 }
  104.               break;
  105.           }
  106.         // use charIshMenu and shortIshMenu to determine what to do, and on what
  107.         case 7: case 8: case 9: case 10: case 11: case 12:
  108.           {
  109.               CIssue *thisIssue, *newIssue;
  110.               NSMenuItem *mi;
  111.               char strDate[10];
  112.               switch (charIshMenu[choice])
  113.                 {
  114.                   // move the selected issue (curIshArray[pubTitle]) to this edit month (shortIshMenu[choice])
  115.                   case 'm':
  116. #if debug
  117.                       NSLog(@"choice m for date %@", [CComics nsStrDate:shortIshMenu[choice]]);
  118. #endif
  119.                       thisIssue = [[thisTitle issues] objectAtIndex:[thisTitle findIssue:[ic curIshArray][pubTitle]]];
  120.                       if (shortIshMenu[choice] != [thisIssue editMonth])
  121.                         {
  122.                           newIssue = [[CIssue alloc] initWithIsh:[thisIssue issueNumber] withEdit:shortIshMenu[choice] withBuy:[thisIssue buyMonth] withFlag:[thisIssue issueFlags]];
  123.                           [thisTitle modIssue:thisIssue withNewIssue:newIssue];
  124.                           mod = 1;
  125.                           [self _updateCurrentEditedRowWithPubRemoval:YES];
  126.                         }
  127.                       break;
  128.                   // select the (shortIshMenu[choice]) issue and put it in curIshArray[pubTitle]
  129.                   // only useful when many issues of the same title are published the same month (weekly and bi-weekly)
  130.                   // see Action Comics run from 601 to 640 for example
  131.                   case 's':
  132. #if debug
  133.                       NSLog(@"choice s for issue %@", [NSString stringWithCString:gnums[shortIshMenu[choice]]]);
  134. #endif
  135.                       for(i=0, j=-1; (j==-1); i++) if (charIshMenu[i] == 'w') j = i;
  136.                       mi = [pub itemAtIndex:j];
  137.                       strcpy(strDate, [[mi title] cString]);
  138.                       strDate[1] = ' ';
  139.                       [mi setTitle:[NSString stringWithCString:strDate]];
  140.                       mi = [pub itemAtIndex:choice];
  141.                       strcpy(strDate, [[mi title] cString]);
  142.                       strDate[1] = '>';
  143.                       [mi setTitle:[NSString stringWithCString:strDate]];
  144.                       charIshMenu[j] = 's';
  145.                       charIshMenu[choice] = 'w';
  146.                       [ic curIshArray][pubTitle] = shortIshMenu[choice];
  147.  
  148.                       [ic setTheBuyMonth:[[[thisTitle issues] objectAtIndex:[thisTitle findIssue:shortIshMenu[choice]]] buyMonth]];
  149.  
  150.                       [self _updateCurrentEditedRowWithPubRemoval:YES];
  151.                       [[[[ic inputView] window] contentView] addSubview:pub];
  152.                       alreadyRemoved = 0;
  153.                       break;
  154.                   // nothing to do here, this menuitem is just for the user to know which issue we're working upon.
  155.                   // it is displayed with a starting ">>"
  156.                   case 'w':
  157. #if debug
  158.                       NSLog(@"choice w for issue %@", [NSString stringWithCString:gnums[shortIshMenu[choice]]]);
  159. #endif
  160.                       break;
  161.                   // add issue (shortIshMenu[choice])
  162.                   // or move it to this edit month (the current column) if it was already existing
  163.                   case 'a':
  164. #if debug
  165.                       NSLog(@"choice a for issue %@", [NSString stringWithCString:gnums[shortIshMenu[choice]]]);
  166. #endif
  167.                       if ((j = ([thisTitle findIssue:shortIshMenu[choice]])) == -1)
  168.                         {
  169.                           newIssue = [[CIssue alloc] initWithIsh:shortIshMenu[choice] withEdit:([ic theEditMonth]-12+pubChoice) withBuy:[ic theBuyMonth] withFlag:defaultFI];
  170.                           [thisTitle addIssue:newIssue];
  171.                           mod = 1;
  172.                           [self _updateCurrentEditedRowWithPubRemoval:YES];
  173.                         }
  174.                       else
  175.                         {
  176.                           short newFlagI;
  177.                           thisIssue = [[thisTitle issues] objectAtIndex:j];
  178.                           newFlagI = ([thisIssue issueFlags] & mskNotGrade) | mskMint;
  179.                           newIssue = [[CIssue alloc] initWithIsh:[thisIssue issueNumber] withEdit:([ic theEditMonth]-12+pubChoice) withBuy:[ic theBuyMonth] withFlag:newFlagI];
  180.                           [thisTitle modIssue:thisIssue withNewIssue:newIssue];
  181.                           mod = 1;
  182.                           [self _updateCurrentEditedRowWithPubRemoval:YES];
  183.                         }
  184.                       break;
  185.                   // delete the issue (shortIshMenu[choice]) except if it is the last one.
  186.                   // I do this to not to have to test against empty issues array in CTitle or CComics methods all the time
  187.                   case 'd':
  188. #if debug
  189.                       NSLog(@"choice d for issue %@", [NSString stringWithCString:gnums[shortIshMenu[choice]]]);
  190. #endif
  191.                       if ([thisTitle nbIssues] > 1)
  192.                         {
  193.                           thisIssue = [[thisTitle issues] objectAtIndex:[thisTitle findIssue:[ic curIshArray][pubTitle]]];
  194.                           [thisTitle deleteIssue:thisIssue];
  195.                           mod = 1;
  196.                           [ic curIshArray][pubTitle] = [[[thisTitle issues] lastObject] issueNumber];
  197.                           [self _updateCurrentEditedRowWithPubRemoval:YES];
  198.                         }
  199.                       else NSRunAlertPanel(@"Comics", @"You can't delete the last issue. Delete the title instead.", @"OK", nil, nil);
  200.                       break;
  201.                   // the "Other..." choice, transform the current cell in an editable one, and start the edition
  202.                   // we'll get the user input in setObjectValue:forTableColumn:row: of InputController
  203.                   case 'o':
  204. #if debug
  205.                       NSLog(@"choice o");
  206. #endif
  207.                       [[[[ic inputView] tableColumns] objectAtIndex:pubChoice] setEditable:YES];
  208.                       [self _updateCurrentEditedRowWithPubRemoval:YES];
  209.                       [[ic inputView] editColumn:pubChoice row:pubTitle withEvent:nil select:YES];
  210.                       break;
  211.                   // nothing to do here, "empty" menu item.
  212.                   case ' ':
  213. #if debug
  214.                       NSLog(@"choice nothing");
  215. #endif
  216.                       break;
  217.                 }
  218.               break;
  219.           }
  220.         // trivial, we modify the issue (from the "Issue" column) attributes
  221.         case 15: case 16: case 17:
  222.           {
  223.               CIssue *thisIssue = [[thisTitle issues] objectAtIndex:[thisTitle findIssue:[ic curIshArray][pubTitle]]];
  224.               short newFlagI = 0, fli = [thisIssue issueFlags];
  225.               switch (pubChoice)
  226.                 {
  227.                   case 15: newFlagI = ((fli & mskNotGrade) | grades[choice]); break;
  228.                   case 16: newFlagI = ((fli & mskNotType ) | types[choice]); break;
  229.                   case 17: newFlagI = ((fli & mskNotCntnt) | cntnts[choice]); break;
  230.                 }
  231.               if (newFlagI != fli)
  232.                 {
  233.                   CIssue *newIssue = [[CIssue alloc] initWithIsh:[thisIssue issueNumber] withEdit:[thisIssue editMonth] withBuy:[thisIssue buyMonth] withFlag:newFlagI];
  234.                   [thisTitle modIssue:thisIssue withNewIssue:newIssue];
  235.                   mod = 1;
  236.                 }
  237.               break;
  238.           }
  239.       }
  240.     // let's not forget to signal that the database has changed
  241.     if (mod) [ic contentChanged];
  242. }
  243.  
  244. - (void)setUpPopup;
  245. {
  246.     pubTitle = [[ic inputView] clickedRow];
  247.     // has the user clicked in an "empty" row?
  248.     if (pubTitle >= [[ic array] count]) return;
  249.     
  250.     pubChoice = [[ic inputView] clickedColumn];
  251.     if ((pubChoice > 2) && (pubChoice != 13) && (pubChoice != 14))
  252.       {
  253.         CTitle *thisTitle = [[ic array] objectAtIndex:pubTitle];
  254.         CIssue *thisIssue = nil;
  255.         char miTitle[10];
  256.         short i, j, k, k2, nbMI;
  257.         NSRect aRect;
  258.  
  259.         // get the rectangle of the clicked cell
  260.         aRect = [[ic inputView] frameOfCellAtColumn:pubChoice row:pubTitle];
  261.         // convert it in window coordinates
  262.         aRect = [[[[ic inputView] window] contentView] convertRect:aRect fromView:[ic inputView]];
  263.         // add a little extra width
  264.         aRect.size.width += 28;
  265.         // and create the pop up button there
  266.         pub = [[NSPopUpButton alloc] initWithFrame:aRect pullsDown:NO];
  267.         [pub setFont:((pubChoice >= 7) && (pubChoice <= 12))?[ic fontNonProp]:[ic fontProp]];
  268.         // and set the target and action so that we know when the user is using it
  269.         [pub setTarget:self];
  270.         [pub setAction:@selector(pubSelect:)];
  271.         // and now let's put some menu items in the pop up depending on the clicked column
  272.         if ((pubChoice >= 14) && (pubChoice <= 16))
  273.             thisIssue = [[thisTitle issues] objectAtIndex:[thisTitle findIssue:[ic curIshArray][pubTitle]]];
  274.         switch (pubChoice)
  275.           {
  276.             case 3:
  277.                 [pub addItemWithTitle:@"Marvel"];
  278.                 [pub addItemWithTitle:@"DC"];
  279.                 [pub addItemWithTitle:@"Other"];
  280.                 [pub selectItemWithTitle:[thisTitle brand]];
  281.                 break;
  282.             case 4:
  283.                 [pub addItemWithTitle:@"Long"];
  284.                 [pub addItemWithTitle:@"Mini"];
  285.                 [pub selectItemWithTitle:[thisTitle series]];
  286.                 break;
  287.             case 5:
  288.                 [pub addItemWithTitle:@"Main"];
  289.                 [pub addItemWithTitle:@"Dual"];
  290.                 [pub selectItemWithTitle:[thisTitle kind]];
  291.                 break;
  292.             case 6:
  293.                 [pub addItemWithTitle:@"Live"];
  294.                 [pub addItemWithTitle:@"Dead"];
  295.                 [pub selectItemWithTitle:[thisTitle tstate]];
  296.                 break;
  297.             case 7: case 8: case 9: case 10: case 11: case 12:
  298.                 j = -1;
  299.                 i = [ic theEditMonth] - 12 + pubChoice;
  300.                 for(k=0; k<5; k++) monthArray[k] = -1;
  301.                 nbma = 0; nbMI = 0;
  302.                 for(k = [thisTitle nbIssues]-1; (k >= 0) && (j == -1); k--)
  303.                     if (([thisIssue = [[thisTitle issues] objectAtIndex:k] editMonth] == i) && !([thisIssue issueFlags] & mskMiss)) j = k;
  304.                 if (j != -1)
  305.                   {
  306.                     [ic setTheBuyMonth:[thisIssue buyMonth]];
  307.                     for(k2=j; (k2>=0) && ([thisIssue = [[thisTitle issues] objectAtIndex:k2] editMonth] == i); k2--)
  308.                         if (!([thisIssue issueFlags] & mskMiss)) monthArray[nbma++] = [thisIssue issueNumber];
  309.                   }
  310.                 if (nbma == 0)
  311.                   {
  312.                     short lastIshP1 = [[[thisTitle issues] lastObject] issueNumber] + 1;
  313.                     [pub addItemWithTitle:[NSString stringWithCString:strcat(strcpy(miTitle, "  "),gnums[lastIshP1])]];
  314.                     charIshMenu[nbMI] = 'a'; shortIshMenu[nbMI++] = lastIshP1;
  315.                     [pub addItemWithTitle:@""]; charIshMenu[nbMI++] = ' ';
  316.                     for(k=lastIshP1-2; k<lastIshP1; k++) if (k >= 0)
  317.                       {
  318.                         [pub addItemWithTitle:[NSString stringWithCString:strcat(strcpy(miTitle, "  "),gnums[k])]];
  319.                         charIshMenu[nbMI] = 'a'; shortIshMenu[nbMI++] = k;
  320.                       }
  321.                     for(k=lastIshP1+1; k<lastIshP1+6; k++)
  322.                       {
  323.                         [pub addItemWithTitle:[NSString stringWithCString:strcat(strcpy(miTitle, "  "),gnums[k])]];
  324.                         charIshMenu[nbMI] = 'a'; shortIshMenu[nbMI++] = k;
  325.                       }
  326.                     [pub addItemWithTitle:@"   "]; charIshMenu[nbMI++] = ' ';
  327.                     [pub addItemWithTitle:@"Other..."];
  328.                     charIshMenu[nbMI] = 'o'; shortIshMenu[nbMI++] = 0;
  329.                   }
  330.                 else
  331.                   {
  332.                     for(k=1; k <= 6; k++)
  333.                       {
  334.                         strcat(strcpy(miTitle, " "), [CComics cStrDate:[ic theEditMonth]-6+k]);
  335.                         [pub addItemWithTitle:[NSString stringWithCString:miTitle]];
  336.                         charIshMenu[nbMI] = 'm'; shortIshMenu[nbMI++] = [ic theEditMonth]-6+k;
  337.                       }
  338.                     [pub addItemWithTitle:@" "]; charIshMenu[nbMI++] = ' ';
  339.                     for(k=nbma-1; k>=0; k--)
  340.                       {
  341.                         strcpy(miTitle, "  ");
  342.                         strcat(miTitle, gnums[monthArray[k]]);
  343.                         miTitle[0] = '>';
  344.                         if (k == 0) miTitle[1] = '>';
  345.                         [pub addItemWithTitle:[NSString stringWithCString:miTitle]];
  346.                         charIshMenu[nbMI] = (k==0)?'w':'s'; shortIshMenu[nbMI++] = monthArray[k];
  347.                       }
  348.                     [pub addItemWithTitle:@""]; charIshMenu[nbMI++] = ' ';
  349.                     for(k=monthArray[nbma-1]-2; k<monthArray[nbma-1]; k++) if (k >= 0)
  350.                       {
  351.                         [pub addItemWithTitle:[NSString stringWithCString:strcat(strcpy(miTitle, "  "),gnums[k])]];
  352.                         charIshMenu[nbMI] = 'a'; shortIshMenu[nbMI++] = k;
  353.                       }
  354.                     for(k=monthArray[0]+1; k<monthArray[0]+6; k++)
  355.                       {
  356.                         [pub addItemWithTitle:[NSString stringWithCString:strcat(strcpy(miTitle, "  "),gnums[k])]];
  357.                         charIshMenu[nbMI] = 'a'; shortIshMenu[nbMI++] = k;
  358.                       }
  359.                     [pub addItemWithTitle:@"  "]; charIshMenu[nbMI++] = ' ';
  360.                     [pub addItemWithTitle:@"Delete"];
  361.                     [ic curIshArray][pubTitle] = monthArray[0];
  362.                     charIshMenu[nbMI] = 'd'; shortIshMenu[nbMI++] = [ic curIshArray][pubTitle];
  363.                     [self _updateCurrentEditedRowWithPubRemoval:NO];
  364.                     [pub addItemWithTitle:@"   "]; charIshMenu[nbMI++] = ' ';
  365.                     [pub addItemWithTitle:@"Other..."];
  366.                     charIshMenu[nbMI] = 'o'; shortIshMenu[nbMI++] = 0;
  367.                   }
  368.                 break;
  369.             case 15:
  370.                 [pub addItemWithTitle:@"Mint"];
  371.                 [pub addItemWithTitle:@"Fine"];
  372.                 [pub addItemWithTitle:@"Good"];
  373.                 [pub addItemWithTitle:@"Poor"];
  374.                 [pub addItemWithTitle:@"Missing"];
  375.                 [pub selectItemWithTitle:[thisIssue grade]];
  376.                 break;
  377.             case 16:
  378.                 [pub addItemWithTitle:@"Comics"];
  379.                 [pub addItemWithTitle:@"Luxe"];
  380.                 [pub addItemWithTitle:@"New Format"];
  381.                 [pub addItemWithTitle:@"Magazine"];
  382.                 [pub selectItemWithTitle:[thisIssue ishtype]];
  383.                 break;
  384.             case 17:
  385.                 [pub addItemWithTitle:@"Story"];
  386.                 [pub addItemWithTitle:@"Info"];
  387.                 [pub addItemWithTitle:@"Reprint"];
  388.                 [pub selectItemWithTitle:[thisIssue content]];
  389.                 break;
  390.           }
  391.         // finally add the pop up button to the content view of the window
  392.         [[[[ic inputView] window] contentView] addSubview:pub];
  393.         // and remember it's here
  394.         alreadyRemoved = 0;
  395.       }
  396. }
  397.  
  398. @end
  399.