home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / C / Applications / MacPerl 5.0.3 / MacPerl Source ƒ / MacPerl5 / MPHelp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-11-28  |  5.9 KB  |  269 lines  |  [TEXT/MPS ]

  1. /*********************************************************************
  2. Project    :    MacPerl            -    Real Perl Application
  3. File        :    MPHelp.c            -    Various helpful functions
  4. Author    :    Matthias Neeracher
  5. Language    :    MPW C
  6.  
  7. $Log: MPHelp.c,v $
  8. Revision 1.1  1994/02/27  23:01:10  neeri
  9. Initial revision
  10.  
  11. Revision 0.2  1993/09/08  00:00:00  neeri
  12. Corrected some misunderstandings of dbm
  13.  
  14. Revision 0.1  1993/08/17  00:00:00  neeri
  15. Use Application directory
  16.  
  17. *********************************************************************/
  18.  
  19. #include "MPHelp.h"
  20. #include "MPConsole.h"
  21. #include "MPUtils.h"
  22.  
  23. #include <Menus.h>
  24. #include <Balloons.h>
  25. #include <ToolUtils.h>
  26. #include <TFileSpec.h>
  27. #include <ndbm.h>
  28. #include <ctype.h>
  29. #include <PLStringFuncs.h>
  30. #include <Folders.h>
  31. #include <fcntl.h>
  32. #include <ioctl.h>
  33. #include <stdio.h>
  34. #include <string.h>
  35.  
  36. static void MetaHelp(StringPtr msg, StringPtr m1, StringPtr m2, StringPtr m3) 
  37. {
  38.     SetCursor(&qd.arrow);
  39.     ParamText(msg, m1, m2, m3);
  40.      Alert(ErrorAlert, nil);
  41. }
  42.  
  43. static MenuHandle    gHelpMenus[20];
  44. static Handle        gHelpURLs[20];
  45. static DBM *         gHelpIndex = nil;
  46. static Boolean        gHasHelp    =    true;
  47.  
  48. void InitHelpIndex()
  49. {
  50.     int            depth       =     0;
  51.     int            curIndex    =    0;
  52.     int            nextIndex=     0;
  53.     MenuHandle    curMenu;
  54.     char *        menu;
  55.     char *        scan;
  56.     char *         next;
  57.     datum         key;
  58.     datum         data;
  59.     Str255        contrib;
  60.     int            menuStack[10];
  61.  
  62.     AppendMenu(myMenus[helpM], "\p-(");
  63.  
  64.     if (!gHelpIndex)
  65.         goto whyNoHelp;
  66.         
  67.     key.dptr     = " MENU";
  68.     key.dsize    = 5;
  69.     data             = dbm_fetch(gHelpIndex, key);
  70.     
  71.     if (!data.dptr)
  72.         goto whyNoHelp;
  73.     
  74.     curMenu                 =    gHelpMenus[curIndex = nextIndex++] = myMenus[helpM];
  75.     menuStack[depth]     =     curIndex;
  76.     PtrToHand("\n\n\n\n\n\n\n\n\n\n", &gHelpURLs[curIndex], CountMItems(curMenu));
  77.     for (menu = data.dptr; depth>=0; menu = next+1) {
  78.         next = strchr(menu, '\n');
  79.         if (menu == next) 
  80.             if (!depth--)
  81.                 break;
  82.             else    {
  83.                 curIndex =     menuStack[depth];
  84.                 curMenu    =    gHelpMenus[curIndex];
  85.                 continue;
  86.             }
  87.         scan             =     strchr(menu, '\t');
  88.         contrib[0]    =    scan - menu;
  89.         memcpy(contrib+1, menu, contrib[0]);
  90.         AppendMenu(curMenu, contrib);
  91.         PtrAndHand(scan+1, gHelpURLs[curIndex], next - scan);
  92.         if (*++scan == '!') {
  93.             curIndex =  nextIndex++;
  94.             gHelpMenus[curIndex] = NewMenu(kHierHelpMenu+curIndex, "\p");
  95.             SetItemCmd(curMenu, CountMItems(curMenu), 0x1B);
  96.             SetItemMark(curMenu, CountMItems(curMenu), kHierHelpMenu+curIndex);
  97.             curMenu = gHelpMenus[curIndex];
  98.             InsertMenu(curMenu, -1);
  99.             gHelpURLs[curIndex]    =    NewHandle(0);
  100.             menuStack[++depth]     =     curIndex;
  101.         }
  102.     }
  103.     return;
  104. whyNoHelp:
  105.     gHasHelp = false;
  106.     AppendMenu(myMenus[helpM], "\pEnabling online Help...");    
  107. }
  108.  
  109. void InitHelp()
  110. {
  111.     CInfoPBRec    info;
  112.     FSSpec BalloonPath;
  113.     
  114.     if (gHelpIndex || !gHasHelp)
  115.         return;
  116.         
  117.     BalloonPath.vRefNum     = gAppVol;
  118.     BalloonPath.parID        = gAppDir;
  119.     PLstrcpy(BalloonPath.name, (StringPtr) "\pMacPerl Help");
  120.  
  121.     if (!FSpCatInfo(&BalloonPath, &info)) 
  122.         if (gHelpIndex = dbm_open(FSp2FullPath(&BalloonPath), DBM_RDONLY, 0))
  123.             return;
  124.             
  125.     if (!FindFolder(
  126.             kOnSystemDisk, 
  127.             kPreferencesFolderType, 
  128.             false, 
  129.             &BalloonPath.vRefNum,
  130.             &BalloonPath.parID)
  131.         && !FSpCatInfo(&BalloonPath, &info) 
  132.     )     
  133.         gHelpIndex = dbm_open(FSp2FullPath(&BalloonPath), DBM_RDONLY, 0);
  134. }
  135.  
  136. void EndHelp()
  137. {
  138.     if (gHelpIndex) {
  139.         dbm_close(gHelpIndex);
  140.         
  141.         gHelpIndex = nil;
  142.     }
  143. }
  144.  
  145. void Explain(DPtr doc)
  146. {
  147.     OSErr            err;
  148.     TEHandle        te;
  149.     datum         key;
  150.     datum         data;
  151.     char *        text;
  152.     int            len;
  153.     short            pos;
  154.     short            start;
  155.     
  156.     InitHelp();
  157.     
  158.     if (!gHelpIndex) {
  159.         MetaHelp(
  160.             "\pTo enable online help, put the file \"MacPerl Help\" "
  161.             "in the same folder as the MacPerl application and "
  162.             "restart MacPerl.", (StringPtr) "\p", (StringPtr) "\p", (StringPtr) "\p");
  163.         return;
  164.     }
  165.  
  166.     if (doc) {
  167.         te = doc->theText;
  168.             
  169.         if (pos = (*te)->selEnd - (*te)->selStart) {
  170.             HLock((*te)->hText);
  171.             text = *(*te)->hText;
  172.             start= (*te)->selStart;
  173.             while (pos && isspace(text[start]))
  174.                 ++start, --pos;
  175.             while (pos && isspace(text[start+pos-1]))
  176.                 --pos;
  177.         }
  178.         if (!pos)
  179.             HUnlock((*te)->hText);
  180.     } else 
  181.         pos = 0;
  182.         
  183.     if (!pos) {
  184.         MetaHelp("\pYou didn't select any text to look up.",
  185.                     (StringPtr) "\p", (StringPtr) "\p", (StringPtr) "\p");
  186.  
  187.         EndHelp();
  188.         
  189.         return;
  190.     }
  191.     
  192.     key.dptr = text+start;
  193.     key.dsize = pos;
  194.     data = dbm_fetch(gHelpIndex, key);
  195.     HUnlock((*te)->hText);
  196.     EndHelp();
  197.     
  198.     if (!data.dptr) {
  199.         Str255    keyStr;
  200.         
  201.         keyStr[0] = key.dsize;
  202.         memcpy(keyStr+1, key.dptr, key.dsize);
  203.         
  204.         MetaHelp("\pUnfortunately, I can't give you any help for \"",
  205.                     keyStr, (StringPtr) "\p\"", (StringPtr) "\p");
  206.     } else 
  207.         LaunchHelpURL(data.dptr, data.dsize);
  208. }    
  209.  
  210. void LaunchHelpURL(char * urlPtr, int urlLen)
  211. {
  212.     OSErr        err;
  213.     char *     text;
  214.     int        len;
  215.     char        url[100];
  216.  
  217.     if (*urlPtr == '!')
  218.         return;     /* False positive */
  219.     if (!strncmp(urlPtr, "file:", 5) && urlPtr[5] != '/') {
  220.         FSSpec     here;
  221.         
  222.         here.vRefNum     = gAppVol;
  223.         here.parID        = gAppDir;
  224.         
  225.         FSpUp(&here);
  226.         strcpy(url, "file:///");
  227.         strcpy(url+8, FSp2FullPath(&here));
  228.         for (text = url+8; text = strchr(text, ':'); *text = '/');
  229.         len = strlen(url);
  230.         if (url[len-1] != '/')
  231.             url[len++] = '/';
  232.         memcpy(url+len, urlPtr+5, urlLen-5);
  233.         len += urlLen-5;
  234.     } else {
  235.         memcpy(url, urlPtr, urlLen);
  236.         len = urlLen;
  237.     }
  238.     
  239.     if (gICInstance) {
  240.         long selStart     = 0;
  241.         long selEnd     = len;
  242.         
  243.         if (!ICLaunchURL(gICInstance, "\p", url, len, &selStart, &selEnd)) 
  244.             return;
  245.     }
  246.     MetaHelp("\pFailed to launch help viewer. "
  247.                 "Please make sure that you have Internet Config 1.2b3 or later "
  248.                 "installed and valid Helpers for http: and file: set", 
  249.                 (StringPtr) "\p", (StringPtr) "\p", (StringPtr) "\p");
  250. }
  251.  
  252. void DoHelp(short menu, short item) 
  253. {
  254.     if (gHasHelp) {
  255.         Handle    urls = gHelpURLs[menu];
  256.         char *    url;
  257.     
  258.         HLock(urls);
  259.         for (url = *urls; --item; url = strchr(url, '\n')+1);
  260.         LaunchHelpURL(url, strchr(url, '\n') - url);
  261.         HUnlock(urls);
  262.     } else
  263.         MetaHelp(
  264.             "\pTo enable online help, put the file \"MacPerl Help\" "
  265.             "in the same folder as the MacPerl application and "
  266.             "restart MacPerl.", (StringPtr) "\p", (StringPtr) "\p", (StringPtr) "\p");
  267. }
  268.  
  269.