home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1995 August / NEBULA.mdf / Apps / DevTools / ClassBuilder / Source / DictManager.m < prev    next >
Encoding:
Text File  |  1993-01-25  |  6.1 KB  |  239 lines

  1.  
  2. /* Generated by Interface Builder */
  3.  
  4. #import "DictManager.h"
  5. #import <strings.h>
  6. #import <stdlib.h>
  7. #import <appkit/Panel.h>
  8. #import <appkit/NXBrowser.h>
  9. #import <appkit/NXBrowserCell.h>
  10. #import <appkit/Text.h>
  11. #import <objc/HashTable.h>
  12.  
  13. #define DICTKNT 3  /* number of dictionaries implemented */
  14. const char *dictType[DICTKNT] = {"@","i","*"} ;
  15. id dict[DICTKNT] ;
  16.  
  17. #define CHUNK 127
  18. char **addString(const char *string, int length, char **list,
  19.         int count)
  20. // Adds the specified string to a list of strings.  It allocates 
  21. // more memory in chunks as needed. Robbed and hacked from
  22. // the BusyBox app.
  23. { if(!list)
  24.     list = (char **)malloc(CHUNK*sizeof(char *));
  25.   list[count] = (char *)malloc((length+1)*sizeof(char));
  26.   strcpy(list[count], string);
  27.   count++;
  28.   if(!(count% CHUNK))
  29.     list = (char **)realloc(list,(((count/CHUNK)+1)*CHUNK)*sizeof(char *));
  30.   list[count] = NULL;
  31.   return list;
  32. }
  33.  
  34. void freeList(char **list)
  35. // Frees the array of strings
  36. { char **strings;
  37.   if(list)
  38.   { strings = list;
  39.     while (*strings)
  40.       free(*strings++);
  41.     free(list);
  42.   }
  43. }
  44.  
  45. char *
  46. copy(aStr)
  47. char *aStr ;
  48. { // mallocs memory for a copy of aStr, returns pointer
  49.   // to copy
  50.   char *newStr ;
  51.   newStr = (char *) malloc(strlen(aStr) + 1) ;
  52.   strcpy(newStr, aStr) ;
  53.   return newStr ;
  54. }
  55.  
  56.  
  57. @implementation DictManager
  58.  
  59. + initialize ;
  60. { // set up the global dictionaries
  61.   int i ;
  62.   for(i = 0 ; i < DICTKNT ; i++)
  63.   { dict[i] = [HashTable new] ;
  64.     [dict[i] initKeyDesc: "*" valueDesc: dictType[i]] ;
  65.   }
  66.   return self ;
  67. }
  68.  
  69.  
  70. + insertKey: (char *) aKey value: (void *) data type: (char *) aType ;
  71. { // insert aKey<->data pair into the dictionary indicated by aType;
  72.   int i ;
  73.   if(!strcmp(aType,"*")) // handle strings as special case
  74.   { if([dict[2] isKey: aKey]) // free up old data
  75.        free([dict[2] insertKey:(const void *) copy(aKey) value:(void *) copy(data)]) ;
  76.     else
  77.       [dict[2] insertKey: (const void *) copy(aKey) value:(void *) copy(data)] ;
  78.   }
  79.   else
  80.   { for(i = 0 ; i < DICTKNT && strcmp(aType,dictType[i]) ; i++) ;
  81.     if([dict[i] isKey: aKey]) // already exists...
  82.       [dict[i] insertKey: (const void *) copy(aKey)  value: (void *) data] ;
  83.     else 
  84.       [dict[i] insertKey: (const void *) copy(aKey)  value: (void *) data] ;
  85.   }
  86.   return self ;
  87. }
  88.       
  89.  
  90. + removeKey: (char *) aKey type: (char *) aType ;
  91. { // insert aKey<->data pair into the dictionary indicated by aType;
  92.   int i ;
  93.   if(!strcmp(aType,"*")) // handle strings as special case
  94.   { if([dict[2] isKey: aKey]) // free up old data
  95.     { free([dict[2] valueForKey: aKey]) ;
  96.       [dict[2] removeKey: aKey] ;
  97.     }
  98.   }
  99.   else
  100.   { for(i = 0 ; i < DICTKNT && strcmp(aType,dictType[i]) ; i++) ;
  101.       [dict[i] removeKey: (const void *) aKey] ;
  102.   }
  103.   return self ;
  104. }
  105.       
  106.  
  107. + (void *) valueForKey: (char *) aKey type: (char *) aType ;
  108. { int i ;
  109.   for(i = 0 ; i < DICTKNT && strcmp(aType,dictType[i]) ; i++) ;
  110.   if(i == DICTKNT)
  111.   { NXRunAlertPanel("CB","Unknown data type: \"%s\"",NULL,NULL,NULL,aType) ;
  112.     return (void *) 0 ;
  113.   }
  114.   else
  115.     return [dict[i] valueForKey: aKey] ;
  116. }
  117.  
  118. - (int)browser:sender fillMatrix:matrix inColumn:(int)column ;
  119. { if(column == 0)
  120.     return DICTKNT ;
  121.   else
  122.   { char typeBuf[24] ;
  123.     int i,j ;
  124.     const void  *key; 
  125.     void  *value; 
  126.     NXHashState  state ;
  127.     id table ;
  128.     char **aList = NULL ;  
  129.     strcpy(typeBuf, 
  130.       [[[browserView matrixInColumn: 0] selectedCell] stringValue]) ;
  131.     for(i = 0 ; i < DICTKNT && strcmp(typeBuf,dictType[i]) ; i++) ;
  132.     table = dict[i] ; 
  133.     state =  [table initState]; 
  134.     j = 0 ;
  135.     while ([table nextState: &state key: &key value: &value]) 
  136.       aList = addString((const char *) key, strlen(key), aList, j++) ;
  137.     freeList(browserList) ;
  138.     browserList = aList ;
  139.     return j ;
  140.   }
  141. }
  142.  
  143.  
  144. - browser:sender loadCell:cell atRow:(int)row inColumn:(int)column ;
  145. { if(column == 0)
  146.   { [cell setStringValue: dictType[row]] ;
  147.     [cell setLeaf: NO] ;
  148.   }
  149.   else
  150.   { [cell setStringValue: browserList[row]] ;
  151.     [cell setLeaf:YES] ;
  152.   }
  153.   return self ;
  154. }
  155.  
  156. - browserHit:sender ;
  157. { char path[128] ;
  158.   char type[2], *key[128] ;
  159.   if([browserView selectedColumn] != 1)
  160.     return self ;
  161.   [browserView setPathSeparator: ' '] ;
  162.   [browserView getPath: path toColumn: 2] ;
  163.   sscanf(path,"%s %s",&type,&key) ;
  164.   if(!strcmp(type,"@"))
  165.   { id anId = (id) [dict[0] valueForKey:key] ; 
  166.     [textView setText: [anId name]] ;
  167.     return self ;
  168.   }
  169.   if(!strcmp(type,"i"))
  170.   { char buf[128] ;
  171.     int i = (int) [dict[1] valueForKey:key] ;
  172.     sprintf(buf,"%d", i) ;
  173.     [textView setText: buf] ;
  174.     return self ;
  175.   }
  176.   if(!strcmp(type,"*"))
  177.   { [textView setText: [dict[2] valueForKey:key]] ;
  178.     return self ;
  179.   }  
  180.   return self ;
  181. }
  182.  
  183. - delete: sender ;
  184. { char path[128] ;
  185.   char type[2], *key[128] ;
  186.   int i = 0;
  187.   // delete the selected dictionary entry
  188.   if([browserView selectedColumn] != 1)
  189.     return self ;
  190.   [browserView setPathSeparator: ' '] ;
  191.   [browserView getPath: path toColumn: 2] ;
  192.   sscanf(path,"%s %s",&type,&key) ;
  193.   if(!strcmp(type,"@"))
  194.      i = 0 ;
  195.   else if(!strcmp(type,"i"))
  196.     i = 1 ;
  197.   else if(!strcmp(type,"*"))
  198.     i = 2 ;
  199.   [dict[i] removeKey:key] ;
  200.   sprintf(path," %s",&type) ;
  201.   [browserView loadColumnZero] ;
  202.   [browserView setPath: path] ;
  203.   [textView setText: ""] ;
  204.   return self ;
  205. }
  206.  
  207. - makeKeyAndOrderFront: sender ;
  208. { [browserView loadColumnZero] ;
  209.   return [super makeKeyAndOrderFront: sender] ;
  210. }
  211.  
  212. - newValue: sender ;
  213. { char path[128] ;
  214.   char type[2], key[128], *theText ;
  215.   int textLen ;
  216.   if([browserView selectedColumn] != 1)
  217.     return self ;
  218.   [browserView setPathSeparator: ' '] ;
  219.   [browserView getPath: path toColumn: 2] ;
  220.   sscanf(path,"%s %s",&type,&key) ;
  221.   if(!strcmp(type,"@"))
  222.   { [textView setText: "Sorry: cannot change value of an id"] ;
  223.     return self ;
  224.   }
  225.   textLen = [textView textLength] ;
  226.   theText = (char *) malloc(textLen + 1) ;
  227.   [textView getSubstring: theText start:0 length: textLen] ; 
  228.   if(!strcmp(type,"i"))
  229.   { int i ;
  230.     sscanf(theText,"%d",&i) ;
  231.     [DictManager insertKey: key value: (void *) i type: "i"] ;
  232.   }
  233.   else if(!strcmp(type,"*"))
  234.     [DictManager insertKey: key value: (void *) theText type: "*"] ;
  235.   free(theText) ;
  236.   return self ;
  237. }  
  238. @end
  239.