home *** CD-ROM | disk | FTP | other *** search
-
- /* Generated by Interface Builder */
-
- #import "DictManager.h"
- #import <strings.h>
- #import <stdlib.h>
- #import <appkit/Panel.h>
- #import <appkit/NXBrowser.h>
- #import <appkit/NXBrowserCell.h>
- #import <appkit/Text.h>
- #import <objc/HashTable.h>
-
- #define DICTKNT 3 /* number of dictionaries implemented */
- const char *dictType[DICTKNT] = {"@","i","*"} ;
- id dict[DICTKNT] ;
-
- #define CHUNK 127
- char **addString(const char *string, int length, char **list,
- int count)
- // Adds the specified string to a list of strings. It allocates
- // more memory in chunks as needed. Robbed and hacked from
- // the BusyBox app.
- { if(!list)
- list = (char **)malloc(CHUNK*sizeof(char *));
- list[count] = (char *)malloc((length+1)*sizeof(char));
- strcpy(list[count], string);
- count++;
- if(!(count% CHUNK))
- list = (char **)realloc(list,(((count/CHUNK)+1)*CHUNK)*sizeof(char *));
- list[count] = NULL;
- return list;
- }
-
- void freeList(char **list)
- // Frees the array of strings
- { char **strings;
- if(list)
- { strings = list;
- while (*strings)
- free(*strings++);
- free(list);
- }
- }
-
- char *
- copy(aStr)
- char *aStr ;
- { // mallocs memory for a copy of aStr, returns pointer
- // to copy
- char *newStr ;
- newStr = (char *) malloc(strlen(aStr) + 1) ;
- strcpy(newStr, aStr) ;
- return newStr ;
- }
-
-
- @implementation DictManager
-
- + initialize ;
- { // set up the global dictionaries
- int i ;
- for(i = 0 ; i < DICTKNT ; i++)
- { dict[i] = [HashTable new] ;
- [dict[i] initKeyDesc: "*" valueDesc: dictType[i]] ;
- }
- return self ;
- }
-
-
- + insertKey: (char *) aKey value: (void *) data type: (char *) aType ;
- { // insert aKey<->data pair into the dictionary indicated by aType;
- int i ;
- if(!strcmp(aType,"*")) // handle strings as special case
- { if([dict[2] isKey: aKey]) // free up old data
- free([dict[2] insertKey:(const void *) copy(aKey) value:(void *) copy(data)]) ;
- else
- [dict[2] insertKey: (const void *) copy(aKey) value:(void *) copy(data)] ;
- }
- else
- { for(i = 0 ; i < DICTKNT && strcmp(aType,dictType[i]) ; i++) ;
- if([dict[i] isKey: aKey]) // already exists...
- [dict[i] insertKey: (const void *) copy(aKey) value: (void *) data] ;
- else
- [dict[i] insertKey: (const void *) copy(aKey) value: (void *) data] ;
- }
- return self ;
- }
-
-
- + removeKey: (char *) aKey type: (char *) aType ;
- { // insert aKey<->data pair into the dictionary indicated by aType;
- int i ;
- if(!strcmp(aType,"*")) // handle strings as special case
- { if([dict[2] isKey: aKey]) // free up old data
- { free([dict[2] valueForKey: aKey]) ;
- [dict[2] removeKey: aKey] ;
- }
- }
- else
- { for(i = 0 ; i < DICTKNT && strcmp(aType,dictType[i]) ; i++) ;
- [dict[i] removeKey: (const void *) aKey] ;
- }
- return self ;
- }
-
-
- + (void *) valueForKey: (char *) aKey type: (char *) aType ;
- { int i ;
- for(i = 0 ; i < DICTKNT && strcmp(aType,dictType[i]) ; i++) ;
- if(i == DICTKNT)
- { NXRunAlertPanel("CB","Unknown data type: \"%s\"",NULL,NULL,NULL,aType) ;
- return (void *) 0 ;
- }
- else
- return [dict[i] valueForKey: aKey] ;
- }
-
- - (int)browser:sender fillMatrix:matrix inColumn:(int)column ;
- { if(column == 0)
- return DICTKNT ;
- else
- { char typeBuf[24] ;
- int i,j ;
- const void *key;
- void *value;
- NXHashState state ;
- id table ;
- char **aList = NULL ;
- strcpy(typeBuf,
- [[[browserView matrixInColumn: 0] selectedCell] stringValue]) ;
- for(i = 0 ; i < DICTKNT && strcmp(typeBuf,dictType[i]) ; i++) ;
- table = dict[i] ;
- state = [table initState];
- j = 0 ;
- while ([table nextState: &state key: &key value: &value])
- aList = addString((const char *) key, strlen(key), aList, j++) ;
- freeList(browserList) ;
- browserList = aList ;
- return j ;
- }
- }
-
-
- - browser:sender loadCell:cell atRow:(int)row inColumn:(int)column ;
- { if(column == 0)
- { [cell setStringValue: dictType[row]] ;
- [cell setLeaf: NO] ;
- }
- else
- { [cell setStringValue: browserList[row]] ;
- [cell setLeaf:YES] ;
- }
- return self ;
- }
-
- - browserHit:sender ;
- { char path[128] ;
- char type[2], *key[128] ;
- if([browserView selectedColumn] != 1)
- return self ;
- [browserView setPathSeparator: ' '] ;
- [browserView getPath: path toColumn: 2] ;
- sscanf(path,"%s %s",&type,&key) ;
- if(!strcmp(type,"@"))
- { id anId = (id) [dict[0] valueForKey:key] ;
- [textView setText: [anId name]] ;
- return self ;
- }
- if(!strcmp(type,"i"))
- { char buf[128] ;
- int i = (int) [dict[1] valueForKey:key] ;
- sprintf(buf,"%d", i) ;
- [textView setText: buf] ;
- return self ;
- }
- if(!strcmp(type,"*"))
- { [textView setText: [dict[2] valueForKey:key]] ;
- return self ;
- }
- return self ;
- }
-
- - delete: sender ;
- { char path[128] ;
- char type[2], *key[128] ;
- int i = 0;
- // delete the selected dictionary entry
- if([browserView selectedColumn] != 1)
- return self ;
- [browserView setPathSeparator: ' '] ;
- [browserView getPath: path toColumn: 2] ;
- sscanf(path,"%s %s",&type,&key) ;
- if(!strcmp(type,"@"))
- i = 0 ;
- else if(!strcmp(type,"i"))
- i = 1 ;
- else if(!strcmp(type,"*"))
- i = 2 ;
- [dict[i] removeKey:key] ;
- sprintf(path," %s",&type) ;
- [browserView loadColumnZero] ;
- [browserView setPath: path] ;
- [textView setText: ""] ;
- return self ;
- }
-
- - makeKeyAndOrderFront: sender ;
- { [browserView loadColumnZero] ;
- return [super makeKeyAndOrderFront: sender] ;
- }
-
- - newValue: sender ;
- { char path[128] ;
- char type[2], key[128], *theText ;
- int textLen ;
- if([browserView selectedColumn] != 1)
- return self ;
- [browserView setPathSeparator: ' '] ;
- [browserView getPath: path toColumn: 2] ;
- sscanf(path,"%s %s",&type,&key) ;
- if(!strcmp(type,"@"))
- { [textView setText: "Sorry: cannot change value of an id"] ;
- return self ;
- }
- textLen = [textView textLength] ;
- theText = (char *) malloc(textLen + 1) ;
- [textView getSubstring: theText start:0 length: textLen] ;
- if(!strcmp(type,"i"))
- { int i ;
- sscanf(theText,"%d",&i) ;
- [DictManager insertKey: key value: (void *) i type: "i"] ;
- }
- else if(!strcmp(type,"*"))
- [DictManager insertKey: key value: (void *) theText type: "*"] ;
- free(theText) ;
- return self ;
- }
- @end
-