home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / Languages / MacGofer 0.22d / MacGofer Sources / mac_dialogs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-05-05  |  17.8 KB  |  1,013 lines  |  [TEXT/MPS ]

  1. /*****************************************************************************
  2.  
  3.   mac_dialogs.c:  Copyright (c) Kevin Hammond 1993.   All rights reserved.
  4.   
  5.   This module contains "generic" dialog handling code, plus a few
  6.   common dialogs (e.g. the standard file dialogs).
  7.  
  8.    NB.  All dialogs should abort to the main loop if a memory fault occurs.
  9.  
  10. *****************************************************************************/
  11.  
  12. #include "mac.h"
  13.  
  14. #pragma segment Dialogs
  15.  
  16. char dlgargs[256];
  17. char *sfbuttontext = dlgargs;
  18. short KeyModifiers = 0;
  19.  
  20. static char  dlgsearch[256];
  21. static short dlgsearchsize = 0;
  22. static Cell  dlgsearchfrom;
  23. ListHandle   dlgsearchlist = NIL;
  24. short         dlgOtherButton = 0;
  25. Boolean         dlgcasesens = FALSE;
  26.  
  27. extern char ftolower();
  28. extern Boolean ReplyExists;
  29. extern Boolean    cursorkey();
  30.  
  31. void highlightDefault();
  32.  
  33. /* Ticks before we give up searching for this item in a list */
  34. #define KEY_THRESHOLD    60
  35.  
  36.  
  37. Handle         gethandle();
  38. ControlHandle     getctlhandle();
  39.  
  40. pascal short    setbutton(), setSFPbutton();
  41.  
  42.  
  43. /*
  44.     Simple OK/Cancel dialog with one editable text box
  45.     The EditText item is a numeric value if numeric
  46.     is TRUE.
  47. */
  48.  
  49. #define    TEXTITEM        3
  50. #define    SCROLLUP        4
  51. #define SCROLLDOWN        5
  52. #define SCROLLUPICON        128
  53. #define SCROLLDOWNICON        129
  54. #define SCROLLUPPRESSEDICON    130
  55. #define SCROLLDOWNPRESSEDICON    131
  56.  
  57.  
  58. int numdialog(dialogrno,itemno,init,min,max)
  59. short dialogrno;
  60. int itemno;
  61. int init, min, max;
  62. {
  63.   DialogPtr etdlg;
  64.   short itemhit;
  65.   char valuestr[20];
  66.   int value = init, newval, time;
  67.   
  68.   sprintf(valuestr,"%d",init);
  69.   
  70.   SetCursor(&(qd.arrow));
  71.   etdlg = GetNewDialog(dialogrno,nil,(WindowPtr) -1);
  72.   
  73.   /* Initialise Parameter */
  74.   SetDlgItemText(etdlg,itemno,valuestr);
  75.  
  76.   /* Now show dialog window */
  77.   ShowWindow(etdlg);
  78.  
  79.   /* Highlight the default (OK) button */
  80.   highlightDefault(etdlg);
  81.   
  82.   for(;;)
  83.     {
  84.       ModalDialog((ModalFilterProcPtr) nil,&itemhit);
  85.       switch(itemhit)
  86.         {
  87.           case OK:
  88.             getitext(gethandle(itemno,etdlg),valuestr);
  89.         value = atoi(valuestr);
  90.  
  91.           case CANCEL:
  92.             DisposDialog(etdlg);
  93.             return(itemhit == OK?value:0);
  94.         
  95.       case SCROLLUP:
  96.       case SCROLLDOWN:
  97.         SetDItemPic(etdlg,itemhit,itemhit==SCROLLUP?SCROLLUPPRESSEDICON:
  98.                                  SCROLLDOWNPRESSEDICON);
  99.         do {
  100.           if(itemhit == SCROLLUP)
  101.             {
  102.           if(++value > max)
  103.                 value = max;
  104.         }
  105.           else
  106.             {
  107.           if(--value < min)
  108.                 value = min;
  109.         }
  110.  
  111.           sprintf(valuestr,"%d",value);
  112.           setitext(gethandle(itemno,etdlg),valuestr);
  113.               SelIText(etdlg,TEXTITEM,0,32767);
  114.           Delay(8,&time);    /* Slow things down a little */
  115.         } while(StillDown());
  116.  
  117.         SetDItemPic(etdlg,itemhit,
  118.                       itemhit==SCROLLUP?SCROLLUPICON:SCROLLDOWNICON);
  119.         break;
  120.  
  121.  
  122.       case TEXTITEM:
  123.             getitext(gethandle(itemno,etdlg),valuestr);
  124.         newval = atoi(valuestr);
  125.         if(newval <=0)
  126.           {
  127.             SysBeep(1);
  128.                 SelIText(etdlg,TEXTITEM,0,32767);
  129.           }
  130.         else
  131.           value = newval;
  132.         }
  133.     }
  134. }
  135.  
  136.  
  137. /*
  138.     Simple Yes/No/Cancel dialog.
  139.  
  140.     button defines the default button.
  141. */
  142.  
  143. int yesnodialog(dialogrno,s1,s2,button)
  144. short dialogrno;
  145. char *s1, *s2;
  146. short button;
  147. {
  148.   DialogPtr yndlg;
  149.   short itemhit;
  150.   
  151.   SetCursor(&(qd.arrow));
  152.   paramtext(s1,s2,"","");
  153.  
  154.   yndlg = GetNewDialog(dialogrno,nil,(WindowPtr) -1);
  155.   ShowWindow(yndlg);
  156.   
  157.   ((DialogPeek)yndlg)->aDefItem = button;
  158.   
  159.   highlightDefault(yndlg);
  160.   
  161.   for(;;)
  162.     {
  163.       ModalDialog((ModalFilterProcPtr) nil,&itemhit);
  164.  
  165.       switch(itemhit)
  166.         {
  167.           case YES:
  168.           case NO:
  169.           case CANCEL:
  170.             DisposDialog(yndlg);
  171.             return(itemhit);
  172.         }
  173.     }
  174. }
  175.  
  176. /*
  177.   Packaged SFGetFile dialog.
  178.   Return the string chosen or "" if cancelled.
  179. */
  180.  
  181. char *getfile(nitems,typelist,msg,buttonstring)
  182. short nitems;
  183. SFTypeList typelist;
  184. char *msg, *buttonstring;
  185. {
  186.   Point where;
  187.   char *filename = "";
  188.   Boolean getOK; 
  189.   StandardFileReply SFReply;
  190.  
  191.   SetCursor(&(qd.arrow));
  192.  
  193.   SetPt(&where,75,35);
  194.   strcpy(sfbuttontext,buttonstring);
  195.  
  196.   if(systemVersion >= 0x0700)
  197.     {
  198. #if 1
  199.       StandardGetFile(NIL,nitems,typelist,&SFReply);
  200. #else
  201.       CustomGetFile(NIL,nitems,typelist,&SFReply,sfGetDialogID,
  202.                    where,setbutton,NIL,NIL,NIL,NIL);
  203. #endif
  204.  
  205.       ReplySpec = SFReply.sfFile;
  206.       getOK = SFReply.sfGood;
  207.     }
  208.   else
  209.     {
  210.       sfgetfile(&where,msg,NIL,nitems,typelist,setbutton,&Reply);
  211.  
  212.       SFReplyToFSSpec(Reply, &ReplySpec);
  213.       getOK = Reply.good;
  214.     }
  215.     
  216.   if(getOK)
  217.     {
  218.        *((char *)ReplySpec.name + (int) *((char *)ReplySpec.name)+1) = '\0';
  219.        filename = (char *)ReplySpec.name+1;
  220.     }
  221.  
  222.   savedir(ReplySpec.vRefNum,ReplySpec.parID,TRUE);
  223.   return(filename);
  224. }
  225.  
  226.  
  227. /*
  228.   Packaged SFGetFile dialog.
  229.   Return the string chosen or "" if cancelled.
  230.   Use the named dialog rather than the standard SF dialog.
  231. */
  232.  
  233. char *askgetfile(nitems,typelist,prompt,buttonstring,dlg6,dlg7)
  234. short nitems;
  235. SFTypeList typelist;
  236. char *prompt, *buttonstring;
  237. short dlg6, dlg7;
  238. {
  239.   Point where;
  240.   FInfo dummyFInfo;
  241.  
  242.  
  243.   SetCursor(&(qd.arrow));
  244.   SetPt(&where,75,35);
  245.   strcpy(sfbuttontext,buttonstring);
  246.  
  247.   if(systemVersion >= 0x0700)
  248.     {
  249.       StandardFileReply Reply;
  250.  
  251.       CustomGetFile(NIL,nitems,typelist,&Reply,dlg7,where,NIL,
  252.                     NIL,NIL,NIL,NIL);
  253.  
  254.       if(Reply.sfGood)
  255.         {
  256.           ReplySpec = Reply.sfFile;
  257.           ReplyExists = HGetFInfo(ReplySpec.vRefNum,ReplySpec.parID,ReplySpec.name,&dummyFInfo) == noErr;
  258.           *((char *)ReplySpec.name + (int) *((char *)ReplySpec.name)+1) = '\0';
  259.           return((char *)ReplySpec.name+1);
  260.     }
  261.       else
  262.         return("");
  263.     }
  264.   else
  265.     {
  266.       if(dlg6 == 0)
  267.         sfgetfile(&where,"",NIL,nitems,typelist,setbutton,&Reply);
  268.       else
  269.         sfpgetfile(&where,"",NIL,nitems,typelist,setSFPbutton,&Reply,dlg6,NIL);
  270.  
  271.       if(Reply.good)
  272.         {
  273.           SFReplyToFSSpec(Reply, &ReplySpec);
  274.           ReplyExists = HGetFInfo(ReplySpec.vRefNum,ReplySpec.parID,ReplySpec.name,&dummyFInfo) == noErr;
  275.  
  276.           *((char *)Reply.fName + (int) *((char *)Reply.fName)+1) = '\0';
  277.           return((char *)Reply.fName+1);
  278.         }
  279.       else
  280.         return("");
  281.     }
  282. }
  283.  
  284.  
  285. /*
  286.   Packaged SFPutFile dialog.
  287.  
  288.   Return the name of the file chosen or "" if cancelled.
  289. */
  290.  
  291. char *putfile(title,defaultfile,buttonstring)
  292. char *title, *defaultfile, *buttonstring;
  293. {
  294.   Point where;
  295.   FInfo dummyFInfo;
  296.   char *filename = "";
  297.   Boolean putOK;
  298.   StandardFileReply SFReply;
  299.  
  300.   SetCursor(&(qd.arrow));
  301.   SetPt(&where,75,35);
  302.   strcpy(sfbuttontext,buttonstring);
  303.  
  304.   
  305.   if(systemVersion >= 0x0700)
  306.     {
  307. #if 1
  308.       StandardPutFile(c2pstr(title),c2pstr(defaultfile),&SFReply);
  309. #else
  310.       CustomPutFile(c2pstr(title),c2pstr(defaultfile),&SFReply,
  311.                     sfPutDialogID,where,setbutton,NIL,NIL,NIL,NIL);
  312. #endif
  313.       (void)p2cstr(title);
  314.       (void)p2cstr(defaultfile);
  315.  
  316.       ReplySpec = SFReply.sfFile;
  317.       putOK = SFReply.sfGood;
  318.     }
  319.   else
  320.     {
  321.       sfputfile(&where,title,defaultfile,setbutton,&Reply);
  322.       SFReplyToFSSpec(Reply, &ReplySpec);
  323.       putOK = Reply.good;
  324.     }
  325.  
  326.   if(putOK)
  327.     {
  328.       *((char *)ReplySpec.name + (int) *((char *)ReplySpec.name)+1) = '\0';
  329.       filename = (char *)ReplySpec.name+1;
  330.     }
  331.  
  332.   if(*filename != '\0')
  333.     ReplyExists = HGetFInfo(ReplySpec.vRefNum,ReplySpec.parID,ReplySpec.name,&dummyFInfo) == noErr;
  334.  
  335.   savedir(ReplySpec.vRefNum,ReplySpec.parID,TRUE);
  336.   return(filename);
  337. }
  338.  
  339.  
  340.  
  341. /*
  342.    Set the text of a button.
  343.    Used as a dialog hook in an SF dialog.
  344. */
  345.  
  346. pascal short setbutton(item,dlg)
  347. short item;
  348. DialogPtr dlg;
  349. {
  350.   static Boolean dohighlight = FALSE;
  351.   if(dohighlight)
  352.     {
  353.       highlightDefault(dlg);
  354.       dohighlight = FALSE;
  355.     }
  356.   
  357.   if(*sfbuttontext != '\0')
  358.     {
  359.       SetButtonTitle(dlg,OK,sfbuttontext);
  360.       dohighlight = TRUE;
  361.       *sfbuttontext = '\0';
  362.     }
  363.   return(item);
  364. }
  365.  
  366.  
  367. /*
  368.    Set the text of a button.
  369.    Used as a dialog hook in an SFP dialog.
  370.    
  371.    We don't highlight the default, since with SFP calls, we can't highlight
  372.    until after first event.
  373.    
  374.    -- MS
  375. */
  376.  
  377. pascal short setSFPbutton(item,dlg)
  378. short item;
  379. DialogPtr dlg;
  380. {
  381.   if(*sfbuttontext != '\0')
  382.     {
  383.       SetButtonTitle(dlg,OK,sfbuttontext);
  384.       *sfbuttontext = '\0';
  385.     }
  386.   return(item);
  387. }
  388.  
  389.  
  390. /*
  391.     Set the title of a button.
  392. */
  393.  
  394. SetButtonTitle(dlg,item,text)
  395. DialogPtr dlg;
  396. short item;
  397. char *text;
  398. {
  399.   setctitle(getctlhandle(item,dlg),text);
  400. }
  401.  
  402.  
  403. /*
  404.     Disable/Enable a button.
  405. */
  406.  
  407. DisableButton(dlg,item)
  408. DialogPtr dlg;
  409. short item;
  410. {
  411.   HiliteControl(getctlhandle(item,dlg),255);
  412. }
  413.  
  414.  
  415. EnableButton(dlg,item)
  416. DialogPtr dlg;
  417. short item;
  418. {
  419.   HiliteControl(getctlhandle(item,dlg),0);
  420. }
  421.  
  422.  
  423.  
  424. /* 
  425.   Get a handle for a dialog item
  426. */
  427.  
  428. Handle gethandle(item,dialogptr)
  429. short item;
  430. DialogPtr dialogptr;
  431. {
  432.   short itemtype;
  433.   Rect itemrect;
  434.   Handle itemhandle;
  435.     
  436.   GetDItem(dialogptr,item,&itemtype,&itemhandle,&itemrect);
  437.   return(itemhandle);
  438. }
  439.  
  440.  
  441. /* 
  442.   Get the type of a dialog item
  443. */
  444.  
  445. short getitemtype(item,dialogptr)
  446. short item;
  447. DialogPtr dialogptr;
  448. {
  449.   short itemtype;
  450.   Rect itemrect;
  451.   Handle itemhandle;
  452.     
  453.   GetDItem(dialogptr,item,&itemtype,&itemhandle,&itemrect);
  454.   return(itemtype);
  455. }
  456.  
  457. GetDlgItemRect(dialogptr, item, itemrect)
  458. DialogPtr dialogptr;
  459. short item;
  460. Rect *itemrect;
  461. {
  462.   short itemtype;
  463.   Handle itemhandle;
  464.     
  465.   GetDItem(dialogptr,item,&itemtype,&itemhandle,itemrect);
  466. }
  467.  
  468.  
  469.  
  470. ControlHandle getctlhandle(item,dialogptr)
  471. short item;
  472. DialogPtr dialogptr;
  473. {
  474.   return((ControlHandle) gethandle(item,dialogptr));
  475. }
  476.  
  477.  
  478.  
  479. /* 
  480.     Highlight the Default button in a dialog
  481. */
  482.  
  483. void highlightDefault(dlgarg)
  484. DialogPtr dlgarg;
  485. {
  486.   DialogPeek dlg = (DialogPeek) dlgarg;
  487.   short button = (dlg)->aDefItem;
  488.   Rect displayRect;
  489.   short itemType;
  490.   Handle itemHandle;
  491.   WindowPtr SavePort;
  492.  
  493.   GetDItem((DialogPtr)dlg,button,&itemType,&itemHandle,&displayRect);
  494.   GetPort(&SavePort);
  495.   SetPort((WindowPtr)dlg);
  496.   PenSize(3,3);
  497.   InsetRect(&displayRect,-4,-4);
  498.   FrameRoundRect(&displayRect,16,16);
  499.   SetPort(SavePort);
  500. }
  501.  
  502.  
  503.  
  504. /*
  505.     Draw the frame around a dialog item.
  506. */
  507.  
  508. DrawFrame(dlg,item)
  509. DialogPtr dlg;
  510. short item;
  511. {
  512.   Rect displayRect;
  513.   short itemType;
  514.   Handle itemHandle;
  515.  
  516.   GetDItem(dlg,item,&itemType,&itemHandle,&displayRect);
  517.   FrameDlgRect(dlg,displayRect);
  518. }
  519.  
  520.  
  521. /*
  522.     Draw the frame around a Rect.
  523. */
  524.  
  525. FrameDlgRect(dlg,rect)
  526. DialogPtr dlg;
  527. Rect rect;
  528. {
  529.   WindowPtr SavePort;
  530.  
  531.   GetPort(&SavePort);
  532.   SetPort((WindowPtr)dlg);
  533.   PenNormal();
  534.   OffsetRect(&rect,2,2);
  535.   FrameRect(&rect);
  536.   SetPort(SavePort);
  537. }
  538.  
  539.  
  540. /*
  541.     Frame a dialog list item.
  542. */
  543.  
  544. FrameDlgList(dlg,rect)
  545. DialogPtr dlg;
  546. Rect rect;
  547. {
  548.   WindowPtr SavePort;
  549.  
  550.   GetPort(&SavePort);
  551.   SetPort((WindowPtr)dlg);
  552.   PenNormal();
  553.   OffsetRect(&rect,2,2);
  554.   SetRect(&rect,rect.left-4,rect.top-3,rect.right-1,rect.bottom-1);
  555.   FrameRect(&rect);
  556.   SetPort(SavePort);
  557. }
  558.  
  559.  
  560. /*
  561.     Set the text of an edittext or static text item.
  562. */
  563.  
  564. SetDlgItemText(dlg,item,text)
  565. DialogPtr dlg;
  566. short item;
  567. char *text;
  568. {
  569.   Handle itemhandle = gethandle(item,dlg);
  570.   setitext(itemhandle,text);
  571.  
  572.   if (getitemtype(item, dlg) == editText)     /* Only select if it's editable */
  573.      SelIText(dlg,item,0,32767);
  574. }
  575.  
  576.  
  577. /*
  578.     Set Dialog item text from an Int value.
  579. */
  580.  
  581.  
  582. SetDlgItemETVal(dlg,item,value)
  583. DialogPtr dlg;
  584. short item;
  585. int value;
  586. {
  587.   char sval[20];
  588.   sprintf(sval,"%d",value);
  589.   SetDlgItemText(dlg,item,sval);
  590. }
  591.  
  592.  
  593. /*
  594.     Get Dialog item value from its text.
  595. */
  596.  
  597. Boolean GetDlgItemETVal(dlg,item,value)
  598. DialogPtr dlg;
  599. short item;
  600. int *value;
  601. {
  602.   char sval[256];
  603.   int temp;
  604.   
  605.   getitext(gethandle(item,dlg),sval);
  606.  
  607.   if((temp = atoi(sval)) > 0)
  608.     {
  609.       *value = temp;
  610.       return(TRUE);
  611.     }
  612.  
  613.   return(FALSE);
  614. }
  615.  
  616.  
  617. /*
  618.     Set the value of a dialog control.
  619. */
  620.  
  621. SetDlgItemValue(dlg,item,value)
  622. DialogPtr dlg;
  623. short item, value;
  624. {
  625.   SetCtlValue(getctlhandle(item,dlg),value);    
  626. }
  627.  
  628.  
  629.  
  630. /*
  631.     Invert the value of a dialog control.
  632.     Used for check-boxes and radio-controls.
  633. */
  634.  
  635. InvertDlgItemValue(dlg,item)
  636. DialogPtr dlg;
  637. short item;
  638. {
  639.   ControlHandle ctlhandle = getctlhandle(item,dlg);
  640.   short itemvalue = GetCtlValue(ctlhandle);    
  641.   SetCtlValue(ctlhandle,!itemvalue);    
  642. }
  643.  
  644.  
  645. /*
  646.     Set the picture for a dialog item to PICT #pic
  647. */
  648.  
  649. SetDItemPic(dialog,item,pic)
  650. DialogPtr dialog;
  651. short item, pic;
  652. {
  653.   Handle OldPicHandle;
  654.   PicHandle NewPicHandle;
  655.   Rect box;
  656.   short itype;
  657.   
  658.   GetDItem(dialog,item,&itype,&OldPicHandle,&box);
  659.   NewPicHandle = GetPicture(pic);
  660.   if(NewPicHandle != NIL)
  661.     SetDItem(dialog,item,itype,(Handle)NewPicHandle,&box);
  662. }
  663.  
  664.  
  665. /*
  666.     Enable standard buttons.
  667. */
  668.  
  669. EnableButtons(dlg)
  670. DialogPtr dlg;
  671. {
  672.   EnableButton(dlg,((DialogPeek)dlg)->aDefItem);
  673.   if(dlgOtherButton != 0)
  674.   EnableButton(dlg,dlgOtherButton);
  675. }
  676.  
  677.  
  678. /*
  679.     Dialog FIlter Procedure for List items.
  680. */
  681.  
  682.  
  683. pascal Boolean ListDlgFilter(dlg,event,itemhit)
  684. DialogPtr dlg;
  685. EventRecord *event;
  686. short *itemhit;
  687. {
  688.   static long lastkey = 0;
  689.   KeyModifiers = event->modifiers;
  690.  
  691.   switch (event->what)
  692.     {
  693.       case keyDown:
  694.       case autoKey:
  695.         {
  696.           char  ch = (char) (event->message & charCodeMask);                         /* Convert to ASCII */
  697.       
  698.       if(ch == '\n' || ch == '\r' || ch == ENTERkey)
  699.         {
  700.           *itemhit = ((DialogPeek)dlg)->aDefItem;
  701.           return(TRUE);
  702.         }
  703.         
  704.       else if ((event->modifiers & cmdKey) != 0)
  705.         {
  706.           if(ch == '.' )
  707.             {
  708.               *itemhit = CANCEL;
  709.           return(TRUE);
  710.         }
  711.             }
  712.         
  713.       else if (ch == ESC)
  714.         {
  715.           *itemhit = CANCEL;
  716.           return(TRUE);
  717.             }
  718.  
  719.       else if (cursorkey(ch))
  720.         {
  721.           dlgarrowkey(dlgsearchlist,(Boolean)(ch==UARROWkey||ch==LARROWkey));
  722.           EnableButtons(dlg);
  723.           lastkey = 0;
  724.         }
  725.  
  726.       else
  727.         {
  728.           /* Reset the search string after a certain interval */
  729.           if (event->when - lastkey > KEY_THRESHOLD)
  730.             {
  731.               dlgsearchsize = 0;
  732.               SetPt(&dlgsearchfrom,0,0);
  733.             }
  734.         
  735.           /* extend the search string and record the time */
  736.           lastkey = event->when;
  737.           dlgsearch[dlgsearchsize++] = ch;
  738.  
  739.           /* Try to find the next matching cell */
  740.           if(findcellmatching(dlgsearch,dlgsearchsize,
  741.                               dlgsearchlist,&dlgsearchfrom,dlgcasesens))
  742.         EnableButtons(dlg);
  743.           else
  744.             dlgsearchsize--;
  745.         }
  746.     }
  747.     break;
  748.  
  749.       /* mouseDown outside any item should reset the selection */
  750.       case mouseDown:
  751.     lastkey = 0;
  752.         if(*itemhit == 0)
  753.       {
  754.             UnsetListSelection(dlgsearchlist);
  755.           return(TRUE);
  756.       }
  757.     break;
  758.     }
  759.  
  760.   return(FALSE);
  761. }
  762.  
  763.  
  764. /*
  765.     Handle arrow keys in a list dialog.
  766. */
  767.  
  768. dlgarrowkey(list,up)
  769. ListHandle list;
  770. Boolean up;
  771. {
  772.   Cell sel;
  773.   Boolean newsel;
  774.  
  775.   SetPt(&sel,0,0);
  776.   newsel = !LGetSelect(TRUE,&sel,list);
  777.  
  778.   if(up || !up && (newsel || LNextCell(TRUE,TRUE,&sel,list)))
  779.     {
  780.       UnsetListSelection(list);
  781.       if(sel.v > 0 && up)
  782.         --sel.v;
  783.     
  784.       /* Force scrolling for the last item in the list */
  785.       if(!up && !newsel)
  786.         {
  787. /*      LDoDraw(FALSE,list);*/
  788.       ++sel.v;
  789.           LSetSelect(TRUE,sel,list);
  790.           LAutoScroll(list);
  791.           LSetSelect(FALSE,sel,list);
  792.       --sel.v;
  793. /*      LDoDraw(TRUE,list);*/
  794.     }
  795.  
  796.       /* Highlight the new item and scroll to it */
  797.       LSetSelect(TRUE,sel,list);
  798.       LAutoScroll(list);
  799.     }
  800. }
  801.  
  802. /*
  803.     Reset Dialog search parameters.
  804. */
  805.  
  806. resetDlgSearch(list,casesens)
  807. ListHandle list;
  808. Boolean casesens;
  809. {
  810.   SetPt(&dlgsearchfrom,0,0);
  811.   dlgsearchsize = 0;
  812.   dlgsearchlist = list;
  813.   dlgcasesens = casesens;
  814. }
  815.  
  816.  
  817. /*
  818.      Find the first matching cell from the location given.
  819. */
  820.  
  821.  
  822. findcellmatching(match,size,list,from,casesens)
  823. char match[];
  824. short size;
  825. ListHandle list;
  826. Cell *from;
  827. Boolean casesens;
  828. {
  829.   char buff[256];
  830.   short len;
  831.   Cell  next;
  832.   SetPt(&next,from->h,from->v);
  833.  
  834.  if(list != NIL)
  835.     {
  836.       while(TRUE)
  837.         {
  838.           len = 255;
  839.           LGetCell(buff,&len,next,list);
  840.       buff[len] = '\0';
  841.           if(len >= size && equalitems(buff,match,size,casesens))
  842.         {
  843.           UnsetListSelection(list);
  844.           LSetSelect(TRUE,next,list);
  845.           HLock((Handle)list);
  846.           SetPt(&((*list)->clikLoc),next.h,next.v);
  847.           HUnlock((Handle)list);
  848.           LAutoScroll(list);
  849.           from->v = next.v;
  850.           return(TRUE);
  851.         }
  852.  
  853.       if(!LNextCell(TRUE,TRUE,&next,list))
  854.         return(FALSE);
  855.     }
  856.     }
  857. }
  858.  
  859.  
  860. int equalitems(i1,i2,len,casesens)
  861. char *i1, *i2;
  862. int len;
  863. Boolean casesens;
  864. {
  865.   int count;
  866.  
  867.   for(count=0; count < len; ++count,++i1,++i2)
  868.     if(casesens)
  869.       {
  870.         if(*i1!=*i2)
  871.           return(FALSE);
  872.       }
  873.     else if(ftolower(*i1)!=ftolower(*i2))
  874.       return(FALSE);
  875.  
  876.   return(TRUE);
  877. }
  878.  
  879.  
  880.  
  881. UnsetListSelection(list)
  882. ListHandle list;
  883. {
  884.   Cell sel;
  885.   
  886.   SetPt(&sel,0,0);
  887.   while(LGetSelect(TRUE,&sel,list))
  888.     LSetSelect(FALSE,sel,list);
  889. }
  890.  
  891.  
  892.  
  893. /*************************************************************************
  894.  
  895.   Error and debug Alerts.
  896.  
  897. *************************************************************************/
  898.  
  899.  
  900.  
  901. /*
  902.   Complain to the user about something.
  903. */
  904.  
  905. void Complain(file,theStringIndex)
  906. char *file;
  907. short theStringIndex;
  908. {
  909.    char complaint[256];
  910.    getindstring(complaint, Res_Complaint_Strings, theStringIndex);
  911.    paramtext(file,complaint,"","");
  912.    SetCursor(&qd.arrow);
  913.    (void) Alert(Res_Complaint_Alert, NIL);
  914. }
  915.  
  916.  
  917. /*
  918.     Show an error dialog.
  919. */
  920.  
  921. Error(e,s)
  922. char *e,  *s;
  923. {
  924.   SetCursor(&(qd.arrow));
  925.   paramtext(e,s,"","");
  926.   StopAlert(Res_Error_Alert,NIL);
  927. }
  928.  
  929.  
  930. /*
  931.     Show an error dialog, and abort to the main program.
  932. */
  933.  
  934. AbortError(e,s)
  935. char *e,  *s;
  936. {
  937.   extern jmp_buf catch_error;
  938.   Error(e,s);
  939.   longjmp(catch_error,1);
  940. }
  941.  
  942.  
  943. /*
  944.     Show an error dialog with an integer argument, 
  945.     and abort to the main program.
  946. */
  947.  
  948.  
  949. AbortErrorN(fmt,n)
  950. char *fmt;
  951. int n;
  952. {
  953.   char s[256];
  954.   sprintf(s,fmt,n);
  955.   AbortError("",s);
  956. }
  957.  
  958. /*
  959.     Show an error dialog, and quit MacGofer.
  960. */
  961.  
  962. FatalError(s)
  963. char *s;
  964. {
  965.   quit = TRUE;
  966.   AbortError("Fatal ",s);
  967. }
  968.  
  969.  
  970.  
  971. /*
  972.     Various dialogs used when debugging.
  973. */
  974.  
  975.  
  976.  
  977. Debug(s)
  978. char *s;
  979. {
  980.   SetCursor(&(qd.arrow));
  981.   paramtext(s,"","","");
  982.   NoteAlert(Res_Debug_Alert,NIL);
  983. }
  984.  
  985.  
  986. Debug2(fmt,a1)
  987. char *fmt, *a1;
  988. {
  989.   char str[256];
  990.  
  991.   sprintf(str,fmt,a1);
  992.   Debug(str);
  993. }
  994.  
  995. Debug3(fmt,a1,a2)
  996. char *fmt, *a1, *a2;
  997. {
  998.   char str[256];
  999.  
  1000.   sprintf(str,fmt,a1,a2);
  1001.   Debug(str);
  1002. }
  1003.  
  1004. Debug4(fmt,a1,a2,a3)
  1005. char *fmt, *a1, *a2, *a3;
  1006. {
  1007.   char str[256];
  1008.  
  1009.   sprintf(str,fmt,a1,a2,a3);
  1010.   Debug(str);
  1011. }
  1012.  
  1013.