home *** CD-ROM | disk | FTP | other *** search
/ Netscape Plug-Ins Developer's Kit / Netscape_Plug-Ins_Developers_Kit.iso / CGIPERL / MACPERL / MSRCE418.HQX / Perl Source ƒ / MacPerl / MPPreferences.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-04  |  24.7 KB  |  1,137 lines

  1. /*********************************************************************
  2. Project    :    MacPerl                -    Real Perl Application
  3. File        :    MPPreferences.c    -    Handle Preference Settings
  4. Author    :    Matthias Neeracher
  5.  
  6. A lot of this code is borrowed from 7Edit written by
  7. Apple Developer Support UK
  8.  
  9. Language    :    MPW C
  10.  
  11. $Log: MPPreferences.c,v $
  12. Revision 1.2  1994/05/04  02:52:40  neeri
  13. Inline Input.
  14.  
  15. Revision 1.1  1994/02/27  23:01:32  neeri
  16. Initial revision
  17.  
  18. Revision 0.1  1993/12/08  00:00:00  neeri
  19. Separated from MPUtils
  20.  
  21. *********************************************************************/
  22.  
  23. #include <PLStringFuncs.h>
  24. #include <Events.h>
  25. #include <Traps.h>
  26. #include <Dialogs.h>
  27. #include <Fonts.h>
  28. #include <Packages.h>
  29. #include <ToolUtils.h>
  30. #include <AppleEvents.h>
  31. #include <TFileSpec.h>
  32. #include <Folders.h>
  33. #include <Resources.h>
  34. #include <OSUtils.h>
  35. #include <Files.h>
  36. #include <Lists.h>
  37. #include <Icons.h>
  38. #include <Script.h>
  39. #include <LowMem.h>
  40. #include <string.h>
  41. #include <GUSI.h>
  42. #include <Desk.h>
  43. #include <ctype.h>
  44. #include <stdio.h>
  45. #include <Balloons.h>
  46.  
  47. #include "MPPreferences.h"
  48. #include "MPUtils.h"
  49. #include "MPWindow.h"
  50. #include <patchlevel.h>
  51.  
  52. pascal void OpenPreferenceFile(FSSpec * spec)
  53. {
  54.     Str255        name;
  55.     short            oldResFile;
  56.     short            res;
  57.     short    **        defaultfont;
  58.     PerlPrefs **prefs;
  59.     
  60.     oldResFile    =    CurResFile();
  61.  
  62.     gPrefsFile = HOpenResFile(spec->vRefNum, spec->parID, spec->name, fsRdWrPerm);
  63.     
  64.     if (gPrefsFile == -1) {
  65.         gPrefsFile = 0;
  66.          
  67.         return;
  68.     }
  69.     
  70.     if (!Get1Resource('STR#', LibraryPaths)) {
  71.         Handle    lib;
  72.         short        count = 1;
  73.         char        len;
  74.         char *    libpath;
  75.         FSSpec    libspec;
  76.         
  77.         libspec.vRefNum    =     gAppVol;
  78.         libspec.parID    =    gAppDir;
  79.         PLstrcpy(libspec.name, (StringPtr) "\plib");
  80.         
  81.         libpath  = FSp2FullPath(&libspec);
  82.         len        = strlen(libpath);
  83.         
  84.         PtrToHand((Ptr) &count, &lib, sizeof(short));
  85.         PtrAndHand((Ptr) &len, lib, 1);
  86.         PtrAndHand(libpath, lib, len);
  87.         
  88.         AddResource(lib, 'STR#', LibraryPaths, (StringPtr) "\p");
  89.     }
  90.     
  91.     if (!(defaultfont = (short **) Get1Resource('PFNT', 128))) {
  92.         Handle    font;
  93.         
  94.         PtrToHand((Ptr) &gFormat.size, &font, sizeof(short));
  95.         GetFontName(gFormat.font, name);
  96.         AddResource(font, 'PFNT', 128, name);
  97.     } else {
  98.         OSType type;
  99.         
  100.         GetResInfo((Handle) defaultfont, &res, &type, name);
  101.         GetFNum(name, &gFormat.font);
  102.         
  103.         if (gFormat.font)
  104.             gFormat.size = **defaultfont;
  105.         else {
  106.             gFormat.font = GetAppFont();
  107.             gFormat.size = GetDefFontSize();
  108.         }
  109.     }
  110.  
  111.     if (!(prefs = (PerlPrefs **) Get1Resource('PPRF', 128))) {
  112.         PtrToHand((Ptr) &gPerlPrefs, (Handle *)&prefs, sizeof(PerlPrefs));
  113.         AddResource((Handle) prefs, 'PPRF', 128, (StringPtr) "\p");
  114.     } else {
  115.         gPerlPrefs.runFinderOpens     = (*prefs)->runFinderOpens;
  116.         gPerlPrefs.checkType           = (*prefs)->checkType;
  117.         if ((*prefs)->version >= PerlPrefVersion413) {
  118.             gPerlPrefs.inlineInput    = (*prefs)->inlineInput;
  119. #ifndef RUNTIME
  120.             if (gTSMTEImplemented)
  121.                 UseInlineInput(gPerlPrefs.inlineInput);
  122. #endif
  123.         }
  124.     }
  125.     
  126.     UseResFile(oldResFile);
  127. }
  128.  
  129. pascal void OpenPreferences()
  130. {
  131.     FSSpec        prefPath;
  132.     CInfoPBRec    info;
  133.     FCBPBRec        fcb;
  134.     Str63            name;
  135.  
  136.     gPrefsFile = 0;
  137.     
  138.     GetFNum((StringPtr) "\pMonaco", &gFormat.font);
  139.     gFormat.size = gFormat.font ? 9 : GetDefFontSize();
  140.     gFormat.font = gFormat.font ? gFormat.font : GetAppFont();
  141.     
  142.     fcb.ioNamePtr    =    (StringPtr) &name;
  143.     fcb.ioRefNum    =    CurResFile();
  144.     fcb.ioFCBIndx    =    0;
  145.     
  146.     PBGetFCBInfoSync(&fcb);
  147.     
  148.     gAppVol    =    fcb.ioFCBVRefNum;
  149.     gAppDir    =    fcb.ioFCBParID;
  150.     
  151.     prefPath.vRefNum     = gAppVol;
  152.     prefPath.parID        = gAppDir;
  153.     PLstrcpy(prefPath.name, (StringPtr) "\pMacPerl Preferences");
  154.     
  155.     if (FSpCatInfo(&prefPath, &info))
  156.         if (FindFolder(
  157.             kOnSystemDisk, 
  158.             kPreferencesFolderType, 
  159.             true, 
  160.             &prefPath.vRefNum,
  161.             &prefPath.parID)
  162.         )
  163.             return;
  164.             
  165.     if (FSpCatInfo(&prefPath, &info)) {
  166.         if (HCreate(prefPath.vRefNum, prefPath.parID, prefPath.name, 'McPL', 'pref'))
  167.             return;
  168.             
  169.         HCreateResFile(prefPath.vRefNum, prefPath.parID, prefPath.name);
  170.     }
  171.     
  172.     OpenPreferenceFile(&prefPath);
  173. }
  174.  
  175. static short        PrefSubDialog     =     1;
  176. static short        PathCount;
  177. static ListHandle    PathList;
  178.  
  179. pascal void DrawPrefIcon(DialogPtr dlg, short item)
  180. {
  181.     short        kind;
  182.     Handle    h;
  183.     Rect        r;
  184.     Str31        title;
  185.     FontInfo    info;
  186.         
  187.     GetDItem(dlg, item, &kind, &h, &r);
  188. #ifndef RUNTIME
  189.     PlotIconID(&r, atNone, (item == PrefSubDialog) ? ttSelected : ttNone, PrefDialog+item);
  190. #else
  191.     PlotResICN_(PrefDialog+item, &r, (item == PrefSubDialog) ? iconHilited : iconPlain);
  192. #endif
  193.     GetIndString(title, PrefDialog, item);
  194.  
  195.     TextFont(1);
  196.     TextSize(9);
  197.     GetFontInfo(&info);
  198.  
  199.     MoveTo(r.left - (StringWidth(title) - 32 >> 1), r.bottom+2+info.ascent);
  200.     DrawString(title);
  201.     
  202.     if (item == PrefSubDialog) {
  203.         
  204.         r.top     = r.bottom + 2;
  205.         r.bottom = r.top + info.ascent+info.descent+info.leading+2;
  206.         r.left     = r.left - (StringWidth(title) - 32 >> 1) - 1;
  207.         r.right  = r.left + StringWidth(title) + 2;
  208.         
  209.         InvertRect(&r);
  210.     }
  211.     
  212.     TextFont(0);
  213.     TextSize(12);
  214. }
  215.  
  216. #if USESROUTINEDESCRIPTORS
  217. RoutineDescriptor    uDrawPrefIcon = 
  218.         BUILD_ROUTINE_DESCRIPTOR(uppUserItemProcInfo, DrawPrefIcon);
  219. #else
  220. #define uDrawPrefIcon *(UserItemUPP)&DrawPrefIcon
  221. #endif
  222.  
  223. pascal void DrawPathList(DialogPtr dlg, short item)
  224. {
  225. #if !defined(powerc) && !defined(__powerc)
  226. #pragma unused(item)
  227. #endif
  228.     Rect    r;
  229.     
  230.     TextFont(0);
  231.     TextSize(12);
  232.     LUpdate(dlg->visRgn, PathList);
  233.     r = (*PathList)->rView;
  234.     InsetRect(&r, -1, -1);
  235.     FrameRect(&r);
  236. }
  237.  
  238. #if USESROUTINEDESCRIPTORS
  239. RoutineDescriptor    uDrawPathList = 
  240.         BUILD_ROUTINE_DESCRIPTOR(uppUserItemProcInfo, DrawPathList);
  241. #else
  242. #define uDrawPathList *(UserItemUPP)&DrawPathList
  243. #endif
  244.  
  245. pascal Boolean PrefLibFilter(DialogPtr dlg, EventRecord * ev, short * item)
  246. {
  247.     Point         cell;
  248.     short            kind;
  249.     short            len;
  250.     int            length;
  251.     Handle        h;
  252.     Rect            r;
  253.     WindowPtr    win;
  254.     char            msg[50];
  255.     char            contents[256];
  256.     
  257.     SetPort(dlg);
  258.     switch (ev->what) {
  259.     case keyDown:
  260.         switch (ev->message & charCodeMask) {
  261.         case '\n':
  262.         case 3:
  263.             *item = pd_Done;
  264.             
  265.             return true;
  266.         case 8:
  267.             *item = pld_Remove;
  268.             
  269.             return true;
  270.         default:
  271.             break;
  272.         }
  273.     case mouseDown:
  274.         switch (FindWindow(ev->where, &win)) {
  275.         case inDrag:
  276.             if (win != dlg)
  277.                 return false;
  278.                 
  279.             r = qd.screenBits.bounds;
  280.             InsetRect(&r, 10, 10);
  281.             DragWindow(win, ev->where, &r);
  282.             
  283.             ev->what = nullEvent;
  284.             
  285.             return false;
  286.         case inSysWindow:
  287.             SystemClick(ev, win);
  288.             
  289.             ev->what = nullEvent;
  290.             
  291.             return false;
  292.         case inContent:
  293.             break;
  294.         default:
  295.             return false;
  296.         }
  297.         TextFont(0);
  298.         TextSize(12);
  299.         cell = ev->where;
  300.         GlobalToLocal(&cell);
  301.         GetDItem(dlg, pld_List, &kind, &h, &r);
  302.         if (PtInRect(cell, &r)) {
  303.             if (LClick(cell, ev->modifiers, PathList))
  304.                 for (SetPt(&cell, 0, 0); LGetSelect(true, &cell, PathList); ++cell.v) {
  305.                     len = 256;
  306.                     LGetCell(contents, &len, cell, PathList);
  307.                     contents[len] = 0;
  308.                     length = 256;
  309.                     getindstring(msg, PrefDialog, pd_ChangePath);
  310.                     if (!choose(AF_FILE, 0, msg, nil, CHOOSE_DEFAULT|CHOOSE_DIR, contents, &length))
  311.                         LSetCell((Ptr) contents, length, cell, PathList);
  312.                 } 
  313.             ev->what = nullEvent;
  314.         }
  315.         break;            
  316.     case activateEvt:
  317.         LActivate(ev->modifiers & activeFlag, PathList);
  318.         break;
  319.     case updateEvt:
  320.         win = (WindowPtr) ev->message;
  321.         if (win != dlg) {
  322.             DoUpdate(DPtrFromWindowPtr(win), win);
  323.             
  324.             ev->what = nullEvent;
  325.         }
  326.         break;
  327.     }
  328.     
  329.     return false;
  330. }
  331.  
  332. #if USESROUTINEDESCRIPTORS
  333. RoutineDescriptor    uPrefLibFilter = 
  334.         BUILD_ROUTINE_DESCRIPTOR(uppModalFilterProcInfo, PrefLibFilter);
  335. #else
  336. #define uPrefLibFilter *(ModalFilterUPP)&PrefLibFilter
  337. #endif
  338.  
  339. static short PrefsLibDialog(DialogPtr prefs, short resFile)
  340. {
  341.     short            item;
  342.     short            kind;
  343.     short            len;
  344.     int            length;
  345.     Boolean        done;
  346.     Handle        h;
  347.     Handle        paths;
  348.     Point            cell;
  349.     Rect            bounds;
  350.     Rect            dbounds;
  351.     char            msg[50];
  352.     Str255        contents;
  353.  
  354.     UseResFile(gPrefsFile);
  355.     
  356.     paths         = Get1Resource('STR#', LibraryPaths);
  357.     PathCount    = **(short **)paths;
  358.  
  359.     UseResFile(resFile);
  360.     
  361. #ifndef RUNTIME
  362.     h    = GetResource('DITL', PrefDialog+PrefSubDialog);
  363.     AppendDITL(prefs, h, overlayDITL); 
  364. #else
  365.     Append_DITL(prefs, PrefDialog+PrefSubDialog);
  366. #endif
  367.  
  368.     GetDItem(prefs, pld_List, &kind, &h, &bounds);
  369.     SetDItem(prefs, pld_List, kind, (Handle) &uDrawPathList, &bounds);
  370.         
  371.     SetPt(&cell, bounds.right - bounds.left, 16);
  372.     SetRect(&dbounds, 0, 0, 1, PathCount);
  373.     PathList = LNew(&bounds, &dbounds, cell, 0, prefs, false, false, false, true);
  374.     
  375.     UseResFile(gPrefsFile);
  376.     SetPt(&cell, 0, 0);
  377.     for (; cell.v < PathCount; ++cell.v) {
  378.         GetIndString(contents, LibraryPaths, cell.v + 1);
  379.         LSetCell((Ptr)contents+1, contents[0], cell, PathList);
  380.     }
  381.     UseResFile(resFile);
  382.     
  383.     LDoDraw(true, PathList);
  384. #ifndef RUNTIME
  385.     HMSetDialogResID(PrefDialog+PrefSubDialog);
  386. #endif
  387.     ShowWindow(prefs);
  388.         
  389.     for (done = false; !done; ) {
  390.         ModalDialog(&uPrefLibFilter, &item);
  391.         switch (item) {
  392.         case pd_Done:
  393.         case pd_ScriptIcon:
  394.         case pd_InputIcon:
  395.             done = true;
  396.             break;
  397.         case pld_Remove:
  398.             SetPt(&cell, 0, 0);
  399.             
  400.             if (LGetSelect(true, &cell, PathList) && Alert(PrefLibDelID, nil) == 1)
  401.                 do {
  402.                     LDelRow(1, cell.v, PathList);
  403.                         
  404.                     --PathCount;
  405.                 } while (LGetSelect(true, &cell, PathList));
  406.                 
  407.             break;
  408.         case pld_Add:
  409.             length = 256;
  410.             getindstring(msg, PrefDialog, pd_AddPath);
  411.             if (!choose(AF_FILE, 0, msg, nil, CHOOSE_DIR, contents, &length)) {
  412.                     SetPt(&cell, 0, PathCount);
  413.                     LAddRow(1, PathCount++, PathList);
  414.                     LSetCell(contents, length, cell, PathList);
  415.             }    
  416.             break;
  417.         }
  418.     }
  419.     
  420.     PtrToXHand(&PathCount, paths, sizeof(short));
  421.     SetPt(&cell, 0, 0);
  422.     for (; cell.v < PathCount; ++cell.v) {
  423.         len = 255;
  424.         LGetCell((Ptr) contents+1, &len, cell, PathList);
  425.         contents[0] = len;
  426.         
  427.         PtrAndHand(contents, paths, len+1);
  428.     }
  429.     
  430.     ChangedResource((Handle) paths);
  431.     WriteResource((Handle) paths);
  432.     
  433.     LDispose(PathList);
  434.  
  435. #ifndef RUNTIME
  436.     ShortenDITL(prefs, CountDITL(prefs) - pd_Outline);
  437. #else
  438.     Shorten_DITL(prefs, Count_DITL(prefs) - pd_Outline);
  439. #endif
  440.  
  441.     return item;
  442. }
  443.  
  444. pascal Boolean PrefScriptFilter(DialogPtr dlg, EventRecord * ev, short * item)
  445. {    
  446.     WindowPtr    win;
  447.     Rect            r;
  448.     
  449.     SetPort(dlg);
  450.     switch (ev->what) {
  451.     case keyDown:
  452.         switch (ev->message & charCodeMask) {
  453.         case '\n':
  454.         case 3:
  455.             *item = pd_Done;
  456.             
  457.             return true;
  458.         default:
  459.             break;
  460.         }
  461.     case mouseDown:
  462.         switch (FindWindow(ev->where, &win)) {
  463.         case inDrag:
  464.             if (win != dlg)
  465.                 return false;
  466.                 
  467.             r = qd.screenBits.bounds;
  468.             InsetRect(&r, 10, 10);
  469.             DragWindow(win, ev->where, &r);
  470.             
  471.             ev->what = nullEvent;
  472.             
  473.             return false;
  474.         case inSysWindow:
  475.             SystemClick(ev, win);
  476.             
  477.             ev->what = nullEvent;
  478.             
  479.             return false;
  480.         default:
  481.             return false;
  482.         }
  483.     case updateEvt:
  484.         win = (WindowPtr) ev->message;
  485.         if (win != dlg) {
  486.             DoUpdate(DPtrFromWindowPtr(win), win);
  487.             
  488.             ev->what = nullEvent;
  489.         }
  490.         break;
  491.     }
  492.     
  493.     return false;
  494. }
  495.  
  496. #if USESROUTINEDESCRIPTORS
  497. RoutineDescriptor    uPrefScriptFilter = 
  498.         BUILD_ROUTINE_DESCRIPTOR(uppModalFilterProcInfo, PrefScriptFilter);
  499. #else
  500. #define uPrefScriptFilter *(ModalFilterUPP)&PrefScriptFilter
  501. #endif
  502.  
  503. static short PrefsScriptDialog(DialogPtr prefs, short resFile)
  504. {
  505.     short            item;
  506.     short            kind;
  507.     Boolean        done;
  508.     Handle        h;
  509.     Handle        pref;
  510.     Rect            bounds;
  511.     
  512. #ifndef RUNTIME
  513.     h    = GetResource('DITL', PrefDialog+PrefSubDialog);
  514.     AppendDITL(prefs, h, overlayDITL); 
  515. #else
  516.     Append_DITL(prefs, PrefDialog+PrefSubDialog);
  517. #endif
  518.     
  519.     GetDItem(prefs, psd_Edit, &kind, &h, &bounds);
  520.     SetControlValue((ControlHandle) h, !gPerlPrefs.runFinderOpens);
  521.     GetDItem(prefs, psd_Run, &kind, &h, &bounds);
  522.     SetControlValue((ControlHandle) h, gPerlPrefs.runFinderOpens);
  523.     GetDItem(prefs, psd_Check, &kind, &h, &bounds);
  524.     SetControlValue((ControlHandle) h, gPerlPrefs.checkType);
  525. #ifndef RUNTIME
  526.     HMSetDialogResID(PrefDialog+PrefSubDialog);
  527. #endif
  528.             
  529.     for (done = false; !done; ) {
  530.         ModalDialog(&uPrefScriptFilter, &item);
  531.         switch (item) {
  532.         case pd_Done:
  533.         case pd_LibIcon:
  534.         case pd_InputIcon:
  535.             done = true;
  536.             break;
  537.         case psd_Edit:
  538.         case psd_Run:
  539.             gPerlPrefs.runFinderOpens = item == psd_Run;
  540.             GetDItem(prefs, psd_Edit, &kind, &h, &bounds);
  541.             SetControlValue((ControlHandle) h, !gPerlPrefs.runFinderOpens);
  542.             GetDItem(prefs, psd_Run, &kind, &h, &bounds);
  543.             SetControlValue((ControlHandle) h, gPerlPrefs.runFinderOpens);
  544.             break;
  545.         case psd_Check:
  546.             gPerlPrefs.checkType = !gPerlPrefs.checkType;
  547.             GetDItem(prefs, psd_Check, &kind, &h, &bounds);
  548.             SetControlValue((ControlHandle) h, gPerlPrefs.checkType);
  549.             break;
  550.         }
  551.     }
  552.  
  553.     UseResFile(gPrefsFile);
  554.     if (pref = Get1Resource('PPRF', 128)) {
  555.         PtrToXHand((Ptr) &gPerlPrefs, pref, sizeof(PerlPrefs));
  556.         ChangedResource((Handle) pref);
  557.         WriteResource((Handle) pref);
  558.     }
  559.     UseResFile(resFile);
  560.  
  561. #ifndef RUNTIME
  562.     ShortenDITL(prefs, CountDITL(prefs) - pd_Outline);
  563. #else
  564.     Shorten_DITL(prefs, Count_DITL(prefs) - pd_Outline);
  565. #endif
  566.  
  567.     return item;
  568. }
  569.  
  570. pascal Boolean PrefInputFilter(DialogPtr dlg, EventRecord * ev, short * item)
  571. {    
  572.     WindowPtr    win;
  573.     Rect            r;
  574.     
  575.     SetPort(dlg);
  576.     switch (ev->what) {
  577.     case keyDown:
  578.         switch (ev->message & charCodeMask) {
  579.         case '\n':
  580.         case 3:
  581.             *item = pd_Done;
  582.             
  583.             return true;
  584.         default:
  585.             break;
  586.         }
  587.     case mouseDown:
  588.         switch (FindWindow(ev->where, &win)) {
  589.         case inDrag:
  590.             if (win != dlg)
  591.                 return false;
  592.                 
  593.             r = qd.screenBits.bounds;
  594.             InsetRect(&r, 10, 10);
  595.             DragWindow(win, ev->where, &r);
  596.             
  597.             ev->what = nullEvent;
  598.             
  599.             return false;
  600.         case inSysWindow:
  601.             SystemClick(ev, win);
  602.             
  603.             ev->what = nullEvent;
  604.             
  605.             return false;
  606.         default:
  607.             return false;
  608.         }
  609.     case updateEvt:
  610.         win = (WindowPtr) ev->message;
  611.         if (win != dlg) {
  612.             DoUpdate(DPtrFromWindowPtr(win), win);
  613.             
  614.             ev->what = nullEvent;
  615.         }
  616.         break;
  617.     }
  618.     
  619.     return false;
  620. }
  621.  
  622. #if USESROUTINEDESCRIPTORS
  623. RoutineDescriptor    uPrefInputFilter = 
  624.         BUILD_ROUTINE_DESCRIPTOR(uppModalFilterProcInfo, PrefInputFilter);
  625. #else
  626. #define uPrefInputFilter *(ModalFilterUPP)&PrefInputFilter
  627. #endif
  628.  
  629. static short PrefsInputDialog(DialogPtr prefs, short resFile)
  630. {
  631.     short            item;
  632.     short            kind;
  633.     Boolean        done;
  634.     Handle        h;
  635.     Handle        pref;
  636.     Rect            bounds;
  637.     
  638. #ifndef RUNTIME
  639.     h    = GetResource('DITL', PrefDialog+PrefSubDialog);
  640.     AppendDITL(prefs, h, overlayDITL); 
  641. #else
  642.     Append_DITL(prefs, PrefDialog+PrefSubDialog);
  643. #endif
  644.     
  645.     GetDItem(prefs, pid_Inline, &kind, &h, &bounds);
  646.     SetControlValue((ControlHandle) h, gPerlPrefs.inlineInput);
  647. #ifndef RUNTIME
  648.     HMSetDialogResID(PrefDialog+PrefSubDialog);
  649. #endif
  650.             
  651.     for (done = false; !done; ) {
  652.         ModalDialog(&uPrefInputFilter, &item);
  653.         switch (item) {
  654.         case pd_Done:
  655.         case pd_LibIcon:
  656.         case pd_ScriptIcon:
  657.             done = true;
  658.             break;
  659.         case pid_Inline:
  660.             gPerlPrefs.inlineInput = !gPerlPrefs.inlineInput;
  661.             GetDItem(prefs, pid_Inline, &kind, &h, &bounds);
  662.             SetControlValue((ControlHandle) h, gPerlPrefs.inlineInput);
  663.             break;
  664.         }
  665.     }
  666.  
  667.     UseResFile(gPrefsFile);
  668.     if (pref = Get1Resource('PPRF', 128)) {
  669.         PtrToXHand((Ptr) &gPerlPrefs, pref, sizeof(PerlPrefs));
  670.         ChangedResource((Handle) pref);
  671.         WriteResource((Handle) pref);
  672.     }
  673.     UseResFile(resFile);
  674.     
  675. #ifndef RUNTIME
  676.     if (gTSMTEImplemented)
  677.         UseInlineInput(gPerlPrefs.inlineInput);
  678.  
  679.     ShortenDITL(prefs, CountDITL(prefs) - pd_Outline);
  680. #else
  681.     Shorten_DITL(prefs, Count_DITL(prefs) - pd_Outline);
  682. #endif
  683.  
  684.     return item;
  685. }
  686.  
  687. pascal void DoPrefDialog()
  688. {
  689.     short            resFile;
  690.     short            kind;
  691.     Handle        h;
  692.     DialogPtr    prefs;
  693.     Rect            bounds;
  694.     
  695.     resFile        = CurResFile();
  696.  
  697.     prefs = GetNewDialog(PrefDialog, nil, (WindowPtr) -1);
  698.  
  699.     GetDItem(prefs, pd_LibIcon, &kind, &h, &bounds);
  700.     SetDItem(prefs, pd_LibIcon, kind, (Handle) &uDrawPrefIcon, &bounds);
  701.  
  702.     GetDItem(prefs, pd_ScriptIcon, &kind, &h, &bounds);
  703.     SetDItem(prefs, pd_ScriptIcon, kind, (Handle) &uDrawPrefIcon, &bounds);
  704.  
  705.     GetDItem(prefs, pd_InputIcon, &kind, &h, &bounds);
  706.     SetDItem(prefs, pd_InputIcon, kind, (Handle) &uDrawPrefIcon, &bounds);
  707.  
  708.     GetDItem(prefs, pd_Boundary, &kind, &h, &bounds);
  709.     SetDItem(prefs, pd_Boundary, kind, (Handle) &uSeparator, &bounds);
  710.  
  711.     AdornDefaultButton(prefs, pd_Outline);
  712.  
  713.     ShowWindow(prefs);
  714.  
  715.     PrefSubDialog = pd_LibIcon;
  716.     PrefSubDialog = PrefsLibDialog(prefs, resFile);
  717.     
  718.     while (PrefSubDialog != pd_Done) {
  719.         SetPort(prefs);
  720.         InvalRect(&prefs->portRect);
  721.         EraseRect(&prefs->portRect);
  722.         switch (PrefSubDialog) {
  723.         case pd_LibIcon:
  724.             PrefSubDialog = PrefsLibDialog(prefs, resFile);
  725.             break;
  726.         case pd_ScriptIcon:
  727.             PrefSubDialog = PrefsScriptDialog(prefs, resFile);
  728.             break;
  729.         case pd_InputIcon:
  730.             PrefSubDialog = PrefsInputDialog(prefs, resFile);
  731.             break;
  732.         }
  733.     }
  734.         
  735.     UpdateResFile(gPrefsFile);
  736.  
  737.     DisposeDialog(prefs);
  738.  
  739. #ifndef RUNTIME
  740.     HMSetDialogResID(-1);
  741. #endif
  742. }
  743.  
  744. static ListHandle FontList;
  745. static ListHandle    SizeList;
  746.  
  747. pascal void DrawFontList(DialogPtr dlg, short item)
  748. {
  749. #if !defined(powerc) && !defined(__powerc)
  750. #pragma unused(item)
  751. #endif
  752.     Rect    r;
  753.     
  754.     TextFont(0);
  755.     TextSize(12);
  756.     LUpdate(dlg->visRgn, FontList);
  757.     r = (*FontList)->rView;
  758.     InsetRect(&r, -1, -1);
  759.     FrameRect(&r);
  760. }
  761.  
  762. #if USESROUTINEDESCRIPTORS
  763. RoutineDescriptor    uDrawFontList = 
  764.         BUILD_ROUTINE_DESCRIPTOR(uppUserItemProcInfo, DrawFontList);
  765. #else
  766. #define uDrawFontList *(UserItemUPP)&DrawFontList
  767. #endif
  768.  
  769. pascal void DrawSizeList(DialogPtr dlg, short item)
  770. {
  771. #if !defined(powerc) && !defined(__powerc)
  772. #pragma unused(item)
  773. #endif
  774.     Rect    r;
  775.     
  776.     TextFont(0);
  777.     TextSize(12);
  778.     LUpdate(dlg->visRgn, SizeList);
  779.     r = (*SizeList)->rView;
  780.     InsetRect(&r, -1, -1);
  781.     FrameRect(&r);
  782. }
  783.  
  784. #if USESROUTINEDESCRIPTORS
  785. RoutineDescriptor    uDrawSizeList = 
  786.         BUILD_ROUTINE_DESCRIPTOR(uppUserItemProcInfo, DrawSizeList);
  787. #else
  788. #define uDrawSizeList *(UserItemUPP)&DrawSizeList
  789. #endif
  790.  
  791. static short SizeChoice[] = 
  792. {
  793.     9,
  794.     10,
  795.     12,
  796.     14,
  797.     18,
  798.     24
  799. };
  800.  
  801. const short    SizeChoiceCount = 6;
  802.  
  803. pascal Boolean FormatFilter(DialogPtr dlg, EventRecord * ev, short * item)
  804. {    
  805.     WindowPtr    win;
  806.     Rect            r;
  807.     
  808.     SetPort(dlg);
  809.     switch (ev->what) {
  810.     case keyDown:
  811.         switch (ev->message & charCodeMask) {
  812.         case '\n':
  813.         case 3:
  814.             *item = fd_OK;
  815.             
  816.             return true;
  817.         case '.':
  818.             if (!(ev->modifiers & cmdKey))
  819.                 break;
  820.         case 27:
  821.             *item = fd_Cancel;
  822.             
  823.             return true;
  824.         default:
  825.             break;
  826.         }
  827.     case mouseDown:
  828.         switch (FindWindow(ev->where, &win)) {
  829.         case inDrag:
  830.             if (win != dlg)
  831.                 return false;
  832.                 
  833.             r = qd.screenBits.bounds;
  834.             InsetRect(&r, 10, 10);
  835.             DragWindow(win, ev->where, &r);
  836.             
  837.             ev->what = nullEvent;
  838.             break;
  839.         case inSysWindow:
  840.             SystemClick(ev, win);
  841.             
  842.             ev->what = nullEvent;
  843.             break;
  844.         }
  845.         return false;
  846.     case activateEvt:
  847.         LActivate(ev->modifiers & activeFlag, FontList);
  848.         LActivate(ev->modifiers & activeFlag, SizeList);
  849.         break;
  850.     case updateEvt:
  851.         win = (WindowPtr) ev->message;
  852.         if (win != dlg) {
  853.             DoUpdate(DPtrFromWindowPtr(win), win);
  854.             
  855.             ev->what = nullEvent;
  856.         }
  857.         break;
  858.     }
  859.     
  860.     return false;
  861. }
  862.  
  863. #if USESROUTINEDESCRIPTORS
  864. RoutineDescriptor    uFormatFilter = 
  865.         BUILD_ROUTINE_DESCRIPTOR(uppModalFilterProcInfo, FormatFilter);
  866. #else
  867. #define uFormatFilter *(ModalFilterUPP)&FormatFilter
  868. #endif
  869.  
  870. short FontCellHeight(MenuHandle fonts, GrafPtr dlg)
  871. {
  872.     short        oldFont;
  873.     short        oldSize;
  874.     short        index;
  875.     short        fontNum;
  876.     short        scriptNum;
  877.     short        minHeight;
  878.     long        scriptsDone;
  879.     long        sysFont;
  880.     FontInfo    fontInfo;
  881.     Str255    contents;
  882.     
  883.     if (GetScriptManagerVariable(smEnabled) < 2)            /* Roman Script Only    */
  884.         return 16;                    /* Ascent + Descent + Leading for Chicago 12 */
  885.     
  886.     SetPort(dlg);
  887.     oldFont         = dlg->txFont;
  888.     oldSize         = dlg->txSize;
  889.     minHeight    = 16;
  890.     scriptsDone    = 0;
  891.     
  892.     for (index=0; index++ < CountMItems(fonts); ) {
  893.         GetItem(fonts, index, contents);
  894.         GetFNum(contents, &fontNum);
  895.         scriptNum = FontToScript(fontNum);
  896.         
  897.         if (scriptNum == smUninterp)
  898.             scriptNum = smRoman;
  899.         /* No point measuring a script more than once */
  900.         if (scriptNum < 32 && (scriptsDone & (1 << scriptNum)))
  901.             continue;
  902.         scriptsDone |= 1 << scriptNum;
  903. #ifndef RUNTIME
  904.         sysFont = GetScriptVariable(scriptNum, smScriptSysFondSize);
  905.         TextFont(sysFont >> 16);
  906.         TextSize(sysFont & 0xFFFF);
  907. #else
  908.         TextFont(GetScriptVariable(scriptNum, smScriptSysFond));
  909.         TextSize(12);
  910. #endif
  911.         GetFontInfo(&fontInfo);
  912.         if (fontInfo.ascent + fontInfo.descent + fontInfo.leading > minHeight)
  913.             minHeight = fontInfo.ascent + fontInfo.descent + fontInfo.leading;
  914.     }
  915.     
  916.     TextFont(oldFont);
  917.     TextSize(oldSize);
  918.     return minHeight;
  919. }
  920.  
  921. pascal void FontLDEF(
  922.     short         message, 
  923.     Boolean         selected, 
  924.     Rect *         cellRect,
  925.     Point            cell,
  926.     short            dataOffset,
  927.     short            dataLen,
  928.     ListHandle    list)
  929. {
  930. #if !defined(powerc) && !defined(__powerc)
  931. #pragma unused(dataOffset)
  932. #endif
  933.     short        oldFont;
  934.     short        oldSize;
  935.     short        fontNum;
  936.     short        scriptNum;
  937.     long        result;
  938.     long        sysFont;
  939.     FontInfo    fontInfo;
  940.     Str255    contents;
  941.     
  942.     switch (message) {
  943.     case lInitMsg:
  944.         if (Gestalt(gestaltQuickdrawVersion, &result) || !result) /* B & W QD */
  945.             (*list)->refCon = 0;
  946.         else
  947.             (*list)->refCon = 1;
  948.     case lDrawMsg:
  949.         SetPort((*list)->port);
  950.         oldFont         = (*list)->port->txFont;
  951.         oldSize         = (*list)->port->txSize;
  952.         LGetCell(contents, &dataLen, cell, list);
  953.         GetFNum(contents, &fontNum);
  954.         scriptNum = FontToScript(fontNum);
  955.             
  956.         if (scriptNum == smUninterp)
  957.             scriptNum = smRoman;
  958.     #ifndef RUNTIME
  959.         sysFont = GetScriptVariable(scriptNum, smScriptSysFondSize);
  960.         TextFont(sysFont >> 16);
  961.         TextSize(sysFont & 0xFFFF);
  962.     #else
  963.         TextFont(GetScriptVariable(scriptNum, smScriptSysFond));
  964.         TextSize(12);
  965.     #endif
  966.         GetFontInfo(&fontInfo);
  967.         MoveTo(cellRect->left+5, cellRect->top + fontInfo.ascent);
  968.         DrawString(contents);
  969.         
  970.         TextFont(oldFont);
  971.         TextSize(oldSize);
  972.         
  973.         if (!selected)
  974.             break;
  975.         
  976.         /* Else fall through to select */
  977.     case lHiliteMsg:
  978.         if ((*list)->refCon)
  979.             LMSetHiliteMode(LMGetHiliteMode() & 0x7F);
  980.         InvertRect(cellRect);
  981.         break;
  982.     default:
  983.         break;
  984.     }
  985. }
  986.  
  987. short FontLDEFID()
  988. {
  989.     if (GetScriptManagerVariable(smEnabled) < 2)            /* Roman Script Only    */
  990.         return 0;
  991.     else 
  992.         return 128;
  993. }
  994.  
  995. pascal Boolean DoFormatDialog(DocFormat * form, Boolean * defaultFormat)
  996. {
  997.     short            item;
  998.     short            kind;
  999.     short         digit;
  1000.     Boolean        done;
  1001.     Handle        h;
  1002.     DialogPtr    format;
  1003.     Point            cell;
  1004.     Rect            bounds;
  1005.     Rect            dbounds;
  1006.     Str255        contents;
  1007.     MenuHandle    fonts;
  1008.     
  1009.     format = GetNewDialog(FormatDialog, nil, (WindowPtr) -1);
  1010.  
  1011.     GetDItem(format, fd_Separator, &kind, &h, &bounds);
  1012.     SetDItem(format, fd_Separator, kind, (Handle) &uSeparator, &bounds);
  1013.  
  1014.     GetDItem(format, fd_FontList, &kind, &h, &bounds);
  1015.     SetDItem(format, fd_FontList, kind, (Handle) &uDrawFontList, &bounds);
  1016.         
  1017.     fonts = NewMenu(FormatDialog, (StringPtr) "\pFonts");
  1018.     AppendResMenu(fonts, 'FONT');
  1019.  
  1020.     bounds.right -= 16;
  1021.     SetPt(&cell, bounds.right - bounds.left, FontCellHeight(fonts, format));
  1022.     SetRect(&dbounds, 0, 0, 1, CountMItems(fonts));
  1023.     FontList = LNew(&bounds, &dbounds, cell, item = FontLDEFID(), format, false, false, false, true);
  1024.     
  1025.     SetPt(&cell, 0, 0);
  1026.     for (; cell.v < CountMItems(fonts); ++cell.v) {
  1027.         GetItem(fonts, cell.v+1, contents);
  1028.         if (item)
  1029.             LSetCell((Ptr)contents, contents[0]+1, cell, FontList);
  1030.         else
  1031.             LSetCell((Ptr)contents+1, contents[0], cell, FontList);
  1032.         GetFNum(contents, &kind);
  1033.         LSetSelect(form->font == kind, cell, FontList);
  1034.     }
  1035.     LAutoScroll(FontList);
  1036.     
  1037.     GetDItem(format, fd_SizeList, &kind, &h, &bounds);
  1038.     SetDItem(format, fd_SizeList, kind, (Handle) &uDrawSizeList, &bounds);
  1039.  
  1040.     bounds.right -= 16;
  1041.     SetPt(&cell, bounds.right - bounds.left, 16);
  1042.     SetRect(&dbounds, 0, 0, 1, SizeChoiceCount);
  1043.     SizeList = LNew(&bounds, &dbounds, cell, 0, format, false, false, false, true);
  1044.     
  1045.     SetPt(&cell, 0, 0);
  1046.     for (; cell.v < SizeChoiceCount; ++cell.v) {
  1047.         sprintf((char *) contents, "%d", SizeChoice[cell.v]);
  1048.         LSetCell((Ptr)contents, strlen((Ptr) contents), cell, SizeList);
  1049.         LSetSelect(form->size == SizeChoice[cell.v], cell, SizeList);
  1050.     }
  1051.     
  1052.     AdornDefaultButton(format, fd_Outline);
  1053.  
  1054.     LDoDraw(true, FontList);
  1055.     LDoDraw(true, SizeList);
  1056.     
  1057.     sprintf((char *) contents+1, "%d", form->size);
  1058.     contents[0] = strlen((Ptr) contents+1);
  1059.     SetText(format, fd_SizeEdit, contents);
  1060.     SelIText(format, fd_SizeEdit, 0, 32767);
  1061.  
  1062.     if (*defaultFormat) {
  1063.         GetDItem(format, fd_MakeDefault, &kind, &h, &bounds);
  1064.         SetControlValue((ControlHandle) h, 1);
  1065.         HiliteControl((ControlHandle) h, 254);
  1066.     }
  1067.     
  1068.     ShowWindow(format);
  1069.         
  1070.     for (done = false; !done; ) {
  1071.         ModalDialog(&uFormatFilter, &item);
  1072.         
  1073.         switch (item) {
  1074.         case fd_OK:
  1075.             RetrieveText(format, fd_SizeEdit, contents);
  1076.             if (contents[0]) {
  1077.                 for (digit = 0, kind = 0; digit++ < contents[0]; )
  1078.                     if (isdigit(contents[digit]))
  1079.                         kind = kind * 10 + contents[digit] - '0';
  1080.                     else {
  1081.                         kind = 0;
  1082.                         
  1083.                         break;
  1084.                     }
  1085.                 
  1086.                 if (kind) {
  1087.                     form->size = kind;
  1088.                     SetPt(&cell, 0, 0);
  1089.                     LGetSelect(true, &cell, FontList);
  1090.                     GetItem(fonts, cell.v+1, contents);
  1091.                     GetFNum(contents, &kind);
  1092.                     form->font = kind;
  1093.                     
  1094.                     done = true;
  1095.                     break;
  1096.                 }
  1097.             }
  1098.             
  1099.             SelIText(format, fd_SizeEdit, 0, 32767);
  1100.             SysBeep(0);
  1101.             
  1102.             item = 0;
  1103.             break;
  1104.         case fd_Cancel:
  1105.             done = true;
  1106.             *defaultFormat = false;
  1107.             break;
  1108.         case fd_FontList:
  1109.             GetMouse(&cell);
  1110.             LClick(cell, 0, FontList);
  1111.             break;
  1112.         case fd_SizeList:
  1113.             GetMouse(&cell);
  1114.             LClick(cell, 0, SizeList);
  1115.             SetPt(&cell, 0, 0);
  1116.             if (LGetSelect(true, &cell, SizeList)) {
  1117.                 sprintf((char *) contents+1, "%d", SizeChoice[cell.v]);
  1118.                 contents[0] = strlen((Ptr) contents+1);
  1119.                 SetText(format, fd_SizeEdit, contents);
  1120.                 SelIText(format, fd_SizeEdit, 0, 32767);
  1121.             }
  1122.             break;
  1123.         case fd_MakeDefault:
  1124.             GetDItem(format, fd_MakeDefault, &kind, &h, &bounds);
  1125.             SetControlValue((ControlHandle) h, *defaultFormat = !*defaultFormat);
  1126.             break;
  1127.         }
  1128.     }
  1129.     
  1130.     LDispose(FontList);
  1131.     LDispose(SizeList);
  1132.     DisposeDialog(format);
  1133.     DisposeMenu(fonts);
  1134.     
  1135.     return (item == fd_OK);
  1136. }
  1137.