home *** CD-ROM | disk | FTP | other *** search
/ NeXTSTEP 3.3 (Developer)…68k, x86, SPARC, PA-RISC] / NeXTSTEP 3.3 Dev Intel.iso / NextDeveloper / Examples / AppKit / Backspace / Thinspector.m < prev    next >
Encoding:
Text File  |  1993-07-15  |  8.3 KB  |  408 lines

  1. //  Thinspector.m
  2. //
  3. //  contains more routines for the Thinker class, mostly related to
  4. //  BackSpace's inspectors.
  5. //
  6. //  You may freely copy, distribute, and reuse the code in this example.
  7. //  NeXT disclaims any warranty of any kind, expressed or  implied, as to its
  8. //  fitness for any particular use.
  9.  
  10. #import "Thinker.h"
  11. #import "BackWindow.h"
  12. #import "BackView.h"
  13. #import "SpaceView.h"
  14. #import "MySlider.h"
  15. #import "Password.h"
  16. #import "psfuncts.h"
  17. #import "ModuleList.h"
  18.  
  19.  
  20. #import <appkit/appkit.h>
  21. #import <objc/NXBundle.h>
  22. #import <sys/dir.h>                /* for opendir(), etc. */
  23.  
  24.  
  25. @implementation Thinker(inspector)
  26.  
  27. - commonImageInspector
  28. {
  29.     return commonImageInspector;
  30. }
  31.  
  32. - nullInspector
  33. {
  34.     return nullInspector;
  35. }
  36.  
  37. - spaceInspector
  38. {
  39.     return spaceInspector;
  40. }
  41.  
  42. - boinkInspector
  43. {
  44.     return boinkInspector;
  45. }
  46.  
  47. - revertToDefaultImage:sender
  48. {
  49.     [self setImageFromName: "defaultImage"];
  50.     NXRemoveDefault([NXApp appName], "imageFile");
  51.     return self;
  52. }
  53.  
  54. - (BOOL)browser:sender columnIsValid:(int)column
  55. {
  56.     return browserValid;
  57. }
  58.  
  59. - addCellWithString:(const char *)str at:(int)row toMatrix:matrix
  60. {
  61.     id theCell;
  62.     
  63.     [matrix insertRowAt:row];
  64.     theCell = [matrix cellAt:row :0];
  65.     [theCell setStringValue:str];
  66.     [theCell setLoaded:YES];
  67.     [theCell setLeaf:YES];
  68.     return self;
  69. }
  70.  
  71. - (int)browser:sender fillMatrix:matrix inColumn:(int)column
  72. {
  73.     const char *ptr;
  74.     int i;
  75.     
  76.     // this shouldn't happen...
  77.     if (browserValid) return [matrix cellCount];
  78.  
  79.     [self addCellWithString:NXLocalString("All", 0, 0)
  80.         at:0 toMatrix:matrix];
  81.     
  82.     for (i = 0; i < [moduleList count]; i++)
  83.         [self addCellWithString:NXLocalString([moduleList nameAt: i], 0, 0)
  84.             at:(i+1) toMatrix:matrix];
  85.             
  86.     realViewIndex = 0;
  87.  
  88.     ptr = NXGetDefaultValue([NXApp appName], "viewType");
  89.     if (ptr)
  90.     {
  91.         for (i = 0; i < [moduleList count]; i++)
  92.         if (strcmp(ptr, [moduleList nameAt: i]) == 0)
  93.         {
  94.             realViewIndex = i+1;
  95.             break;
  96.         }
  97.     }
  98.     
  99.     browserValid = YES;
  100.     return [matrix cellCount];
  101. }
  102.  
  103.  
  104. //  Dynamically load all object files found in the specified directory
  105. //    if we find a module in several places, we save the additional paths
  106. //    in case they point to modules for different architectures
  107.  
  108. - loadViewsFrom: (const char *) dirname
  109. {
  110.     DIR *dir;
  111.     struct direct *de;
  112.     char path[MAXPATHLEN];
  113.     char name[60];
  114.     char *iptr;
  115.     ModuleInfo *m;
  116.     BOOL validName, filePackage;
  117.  
  118.  
  119.     dir = opendir(dirname);
  120.     if (dir == NULL) {
  121.         //perror(dirname);
  122.         return self;
  123.     }
  124.  
  125.     while ((de = readdir(dir)) != NULL)
  126.     {
  127.         int i, numstrings;
  128.     
  129.         // Ignore '.'-files (not really necessary, I guess)
  130.         if (de->d_name[0] == '.')
  131.             continue;
  132.  
  133.         filePackage = validName = NO;
  134.         if (de->d_namlen > 10 && 
  135.                 !strcmp(&de->d_name[de->d_namlen-10], "View.BackO"))
  136.         {
  137.             validName = YES;
  138.             filePackage = NO;
  139.         }
  140.         else if (de->d_namlen > 15 && 
  141.                 !strcmp(&de->d_name[de->d_namlen-15], "View.BackModule"))
  142.         {
  143.             validName = YES;
  144.             filePackage = YES;
  145.         }
  146.  
  147.         if (!validName) continue;
  148.  
  149.  
  150.         // refuse to load if the name matches a module already loaded
  151.         numstrings = [moduleList count];
  152.         strcpy(name, de->d_name);
  153.  
  154.         // Smash out the 'V' in "FooView.BackO"
  155.         if (iptr = rindex(name, 'V'))
  156.             *iptr = '\0';
  157.  
  158.         for (i=0; i< numstrings; i++)
  159.         {
  160.             if (!strcmp(name, [moduleList nameAt:i]))
  161.             {
  162.                 // we already have a module with this name, but will save the path anyway
  163.                 validName = NO;
  164.                 if (filePackage) sprintf(path,"%s/%sView.BackModule",dirname,name);
  165.                 else strcpy(path, dirname);
  166.                 [[moduleList objectAt:i] appendPath:path];
  167.                 break;
  168.             }
  169.         }
  170.         if (!validName) continue;
  171.         
  172.         // I used to load the class at this time; this got horribly
  173.         // inefficient.  I now wait until I'm about to instantiate
  174.         // a view before doing this (thanx bbum!)
  175.  
  176.         if (filePackage) sprintf(path,"%s/%sView.BackModule",dirname,name);
  177.         else strcpy(path, dirname);
  178.         
  179.         m = [[ModuleInfo alloc] 
  180.             initWithView:NULL name:name path:path];
  181.         [moduleList addObject: m];
  182.     }
  183.  
  184.     closedir(dir);
  185.  
  186.     return self;
  187. }
  188.  
  189. - (BOOL)appAcceptsAnotherFile:sender
  190. {
  191.     // return openAnother;
  192.     // if I just return openAnother, I fail to open the module if
  193.     // I get launched to do it.  Punt until I think of a better solution.
  194.     return YES;
  195. }
  196.  
  197. - (int)app:sender openFile:(const char *)filename type:(const char *)aType
  198. {
  199.     // Here we have caught BackSpace off guard; Speaker says open a file,
  200.     // but BackSpace is already locked on a view because it doesn't unlock
  201.     // focus or bail out of the event loop unless there's an event.
  202.     // This is good for performance but it means it handles openfile badly;
  203.     // it must post an event telling it to bail out of the event loop and
  204.     // open the file later; multi file opens are therefore broken, and
  205.     // the return value here is bogus...
  206.     
  207.     char path[MAXPATHLEN];
  208.     NXEvent anEvent;
  209.     char *iptr;
  210.  
  211.     if (fileToOpen)
  212.     {    free(fileToOpen);
  213.         fileToOpen = NULL;
  214.     }
  215.     
  216.     strcpy(path,filename);
  217.  
  218.     if (!strcmp(aType,"BackModule"))
  219.     {
  220.         iptr = rindex(filename, '/');
  221.         strcat(path,iptr);            // /xxx/fooView.BackModule/fooView.BackModule
  222.         iptr = rindex(path, 'M');
  223.         strcat(iptr,"O");            // /xxx/fooView.BackModule/fooView.BackO
  224.     }
  225.  
  226.     fileToOpen = NXCopyStringBuffer(path);
  227.     openAnother = NO;
  228.         
  229.     anEvent.type = NX_APPDEFINED;
  230.     anEvent.data.compound.subtype = BSOPENFILE;
  231.     anEvent.ctxt = [NXApp context];
  232.     DPSPostEvent(&anEvent,0);
  233.     return YES;
  234. }
  235.  
  236. - doDelayedOpenFile
  237. {
  238.     int i, numstrings;
  239.     int ret = YES;
  240.     char path[MAXPATHLEN];
  241.     id theMatrix;
  242.     char *name;
  243.     char *iptr;
  244.     ModuleInfo *m;
  245.  
  246.     numstrings = [moduleList count];
  247.     strcpy(path, fileToOpen);
  248.  
  249.     if ((name = rindex(path, '/')) != NULL)
  250.         *name = '\0';
  251.     name++;
  252.  
  253.     // Smash out the 'V' in "FooView.BackO"
  254.     if ((iptr = rindex(name, 'V')) != NULL)
  255.         *iptr = '\0';
  256.  
  257.     for (i=0; i< numstrings; i++)
  258.     {
  259.         if (!strcmp(name, [moduleList nameAt:i]))
  260.         {    ret = NO;
  261.             break;
  262.         }
  263.     }
  264.         
  265.     if (ret)
  266.     {
  267.         m = [[ModuleInfo alloc] 
  268.             initWithView:NULL name:name path:path];
  269.         [moduleList addObject: m];
  270.  
  271.         browserValid = NO;
  272.         [moduleList sort];
  273.     
  274.         [viewSelectionBrowser loadColumnZero];
  275.     }
  276.     
  277.     theMatrix = [viewSelectionBrowser matrixInColumn:0];
  278.     numstrings = [moduleList count];
  279.     for (i=0; i< numstrings; i++)
  280.     {
  281.         if (!strcmp(name, [moduleList nameAt:i]))
  282.             break;
  283.     }
  284.     realViewIndex = i+1;
  285.         
  286.     [theMatrix selectCellAt:realViewIndex :0];
  287.     [theMatrix scrollCellToVisible:realViewIndex :0];
  288.     [viewSelectionBrowser display];
  289.  
  290.     [self setVirtualViewIndexAndIncrement:NO];
  291.  
  292.     free(fileToOpen);
  293.     fileToOpen = NULL;
  294.     openAnother = YES;
  295.     
  296.     return self;
  297. }
  298.  
  299.  
  300. extern const char *appDirectory();
  301. - (const char *) appDirectory
  302. {
  303.     return appDirectory();
  304. }
  305.  
  306. - (const char *) moduleDirectory:(const char *)name
  307. {
  308.     int i, numstrings;
  309.     
  310.     numstrings = [moduleList count];
  311.     for (i=0; i< numstrings; i++)
  312.     {
  313.         if (!strcmp(name, [moduleList nameAt:i]))
  314.             return [[moduleList objectAt:i] path];
  315.     }
  316.     return NULL;
  317. }
  318.  
  319. - (struct mach_header *) headerForModule:(const char *)name
  320. {
  321.     int i, numstrings;
  322.     
  323.     numstrings = [moduleList count];
  324.     for (i=0; i< numstrings; i++)
  325.     {
  326.         if (!strcmp(name, [moduleList nameAt:i]))
  327.             return [[moduleList objectAt:i] header];
  328.     }
  329.     return NULL;
  330. }
  331.  
  332.  
  333.  
  334.  
  335. static char *launchDir = NULL;    /* if this is NULL, it will be calculated */
  336.  
  337. /**
  338.  **    which-dir -- find the path for the named exectuable file
  339.  ** Returns malloc'd string if it finds it, or NULL if it can't
  340.  **
  341.  **    borrowed from Lennart, munged by sam
  342.  **/
  343.  
  344. const char *which_dir(const char *file)
  345. {
  346.     char buf[MAXPATHLEN];
  347.     char *paths, *p, *q;
  348.     char *ret;
  349.     int dirlen;
  350.  
  351.     paths = getenv("PATH");
  352.     if (paths == NULL) return NULL;
  353.  
  354.     for (p = q = paths; *q != '\0'; p = q + 1)
  355.     {
  356.         q = index(p, ':');
  357.         if (q == NULL) q = p + strlen(p);
  358.  
  359.         dirlen = q - p;
  360.  
  361.         sprintf(buf, "%.*s/%s", dirlen, p, file);
  362.         if (access(buf, X_OK) != 0) continue;
  363.  
  364.         buf[dirlen] = '\0';
  365.         ret = malloc((dirlen+1)*sizeof(char));
  366.         strcpy(ret,buf);
  367.         return ret;
  368.     }
  369.     return NULL;
  370. }
  371.  
  372. const char *appDirectory()
  373. {
  374.     char buf[MAXPATHLEN];
  375.     char *suffix, *path;
  376.  
  377.     if (launchDir) return launchDir;
  378.     
  379.     strcpy (buf,NXArgv[0]);
  380.     suffix = rindex(buf,'/');
  381.     if (suffix != NULL)            // explicit path
  382.     {
  383.         *suffix = '\0';         // remove executable name
  384.     }
  385.     else
  386.     {
  387.         path = (char *)which_dir([NXApp appName]);
  388.         if (path != NULL)
  389.         {
  390.             launchDir = path;
  391.             return launchDir;
  392.         }
  393.         else
  394.         {
  395.             // Don't know where we came from -- arbitrarily
  396.             // presume "." and continue (it's better than breaking)
  397.             strcpy(buf, ".");
  398.         }
  399.     }
  400.  
  401.     launchDir = malloc((strlen(buf)+1)*sizeof(char));
  402.     strcpy(launchDir,buf);
  403.     return launchDir;
  404. }
  405.  
  406. @end
  407.  
  408.