This is ToolBuilder.m in view mode; [Download] [Up]
// ToolBuilder.m // By Charles G. Fleming, Educational Computing Services, Allegheny College. // Copyright 1993, Allegheny College. // You may freely copy, distribute and reuse this code. // Allegheny College and the author disclaim any warranty of any kind, // expressed or implied, as to its fitness for any particular use. #import "ToolBuilder.h" #import "SaverAndRetriever.h" #import "NibSaver.h" #import <ansi/ctype.h> @implementation ToolBuilder - appDidInit:sender { NXBundle *mainBundle; char bundleDirectory[MAXPATHLEN+1]; mainBundle = [NXBundle mainBundle]; strcpy(bundleDirectory, [mainBundle directory]); [(FileRetriever *)connectorFileRetriever setDirectory:bundleDirectory]; [(FileRetriever *)connectorFileRetriever setFilename:"connectorList"]; [connectorFileRetriever open]; [self makeKeyAndOrderFront:self]; return self; } // Start with an empty matrix. - setConnectorMatrix:anObject { connectorMatrix = anObject; [connectorMatrix removeRowAt:0 andFree:YES]; [connectorMatrix removeRowAt:0 andFree:YES]; return self; } - setClassnameTextField:anObject { NXRect textRect = {0, 0, 1E38, 1E38}, textFieldRect = {0, 0, 315, 44}; id accessoryView; Font *font; classnameTextField = anObject; scratchText = [[Text allocFromZone:[self zone]] initFrame:&textRect text:"" alignment:NX_LEFTALIGNED]; [scratchText setMonoFont:YES]; [scratchText setFont:[Font newFont:"Courier" size:14]]; // Get the open panel. We'll use it to select the directory where the // files created will be stored. openPanel = [OpenPanel new]; [openPanel chooseDirectories:YES]; accessoryView = [[TextField allocFromZone:[self zone]] initFrame:&textFieldRect]; font = [Font newFont:"Helvetica" size:16]; [[accessoryView cell] setFont:font]; [accessoryView setStringValue:"Select a directory where the class " "files should be stored."]; [accessoryView setAlignment:NX_CENTERED]; [accessoryView setBackgroundGray:NX_LTGRAY]; [accessoryView setBezeled:NO]; [accessoryView setSelectable:NO]; [openPanel setAccessoryView:accessoryView]; return self; } - createClassFiles:sender { NXBundle *mainBundle; const char *classname; char *classnameM, *classnameH, *classnameInspectorM, *classnameInspectorH; char inspectorPath[MAXPATHLEN+1], inspectorNibDirectory[MAXPATHLEN+1]; int length; // Get the name of the class. classname = [classnameTextField stringValue]; if(length = strlen(classname)) { [self constructSetMethodStrings]; // Select the directory where the class files will be stored. if([openPanel runModal]) { [self makeFirstResponder:self]; strcpy(resultsDirectory, [(OpenPanel *)openPanel filename]); [(FileSaver*)fileSaver setDirectory:resultsDirectory]; length = length+3; classnameM = (char *)malloc(length); classnameH = (char *)malloc(length); sprintf(classnameM, "%s.m", classname); sprintf(classnameH, "%s.h", classname); [self convertFile:"ToolTemplate" ext:"m" destination:classnameM]; [self convertFile:"ToolTemplate" ext:"h" destination:classnameH]; free(classnameM); free(classnameH); if([createInspectorButton state]) { classnameInspectorM = (char *)malloc(length + 10); classnameInspectorH = (char *)malloc(length + 10); sprintf(classnameInspectorM, "%sInspector.m", classname); sprintf(classnameInspectorH, "%sInspector.h", classname); [self convertFile:"ToolInspectorTemplate" ext:"m" destination:classnameInspectorM]; [self convertFile:"ToolInspectorTemplate" ext:"h" destination:classnameInspectorH]; free(classnameInspectorM); free(classnameInspectorH); // Create a directory for the inspector's nib file. sprintf(inspectorNibDirectory, "%s/%sInspector.nib", resultsDirectory, classname); mkdir(inspectorNibDirectory, 00755); // Get the path to the .nib template. mainBundle = [NXBundle mainBundle]; [mainBundle getPath:inspectorPath forResource:"InspectorTemplate" ofType:"nib"]; // Copy the inspector's template nib file to the correct // location. [(FileRetriever *)nibFileRetriever setDirectory:inspectorPath]; [(FileRetriever *)nibFileRetriever setFilename:"data.classes"]; [nibFileRetriever open]; [(FileSaver *)nibFileSaver setDirectory:inspectorNibDirectory]; [(FileSaver *)nibFileSaver setFilename:"data.classes"]; [nibFileSaver save]; [(FileRetriever *)nibFileRetriever setDirectory:inspectorPath]; [(FileRetriever *)nibFileRetriever setFilename:"data.nib"]; [nibFileRetriever open]; [(FileSaver *)nibFileSaver setDirectory:inspectorNibDirectory]; [(FileSaver *)nibFileSaver setFilename:"data.nib"]; [nibFileSaver save]; [nibSaver freeStream]; } // Make a copy of ToolsAndInspectorProtocols.h. [self convertFile:"ToolAndInspectorProtocols" ext:"h" destination:"ToolAndInspectorProtocols.h"]; } } else NXRunAlertPanel("Error", "Missing Class Name", NULL, NULL, NULL); return self; } // Replace the string XXXX in the template file by the name of the class. - insertClassname { const char *classname; classname = [classnameTextField stringValue]; while([scratchText findText:"XXXX" ignoreCase:NO backwards:YES wrap:YES]) [scratchText replaceSel:classname]; return self; } // Replace the string "SETMETHODSM" in ToolTemplate.m by the setMethods // for the connectors. - insertSetMethodsInM { [scratchText findText:"SETMETHODSM" ignoreCase:NO backwards:YES wrap:YES]; if(numConnectors) [scratchText replaceSel:setMethodsMString]; else [scratchText replaceSel:""]; return self; } // Replace the string "SETMETHODSH" in ToolTemplate.h by the setMethods // for the connectors. - insertSetMethodsInH { [scratchText findText:"SETMETHODSH" ignoreCase:NO backwards:YES wrap:YES]; if(numConnectors) [scratchText replaceSel:setMethodsHString]; else [scratchText replaceSel:""]; return self; } // Replace the string "CONNECTORSTRING" in ToolTemplate.m by the list of // connectors separated by commas. - insertConnectorStringInM { [scratchText findText:"CONNECTORSTRING" ignoreCase:NO backwards:YES wrap:YES]; [scratchText replaceSel:connectorString]; return self; } // Replace the string "CONNECTORIDS" in ToolTemplate.h by the id's for // the connectors. - insertConnectorIdStringInH { [scratchText findText:"CONNECTORIDS" ignoreCase:NO backwards:YES wrap:YES]; [scratchText replaceSel:connectorIdString]; return self; } // Get the class template file, create a corresponding class file and // save it. - (BOOL)convertFile:(char *)resource ext:(char *)extension destination:(char *)classname { NXBundle *mainBundle; BOOL success = NO, resourceFound; char *lastSlash; mainBundle = [NXBundle mainBundle]; resourceFound = [mainBundle getPath:fullPath forResource:resource ofType:extension]; if(resourceFound) { lastSlash = rindex(fullPath, '/'); *lastSlash = '\0'; strcpy(directory, fullPath); strcpy(filename, lastSlash+1); [(FileRetriever *)fileRetriever setDirectory:directory]; [fileRetriever setFilename:filename]; if([fileRetriever open]) { [self insertClassname]; if(strcmp("ToolTemplate", resource) == 0) { if(strcmp(extension, "m") == 0) { [self insertSetMethodsInM]; [self insertConnectorStringInM]; } else { [self insertConnectorIdStringInH]; [self insertSetMethodsInH]; } } [fileSaver setFilename:classname]; if([fileSaver save]) success = YES; else success = NO; } else success = NO; } else success = NO; return success; } // Construct the setMethod strings for Tool.m and Tool.h. Also construct // a comma separated list of connectors for Tool.m. - constructSetMethodStrings { const char *title; char *firstTab, *setMethodString, *connectorLine, *lastTab; char **connectorNames; int rows, cols, row, titleLength, totalNameLength; ButtonCell *buttonCell; // Construct a list of the connectors the tool will need. [connectorMatrix getNumRows:&rows numCols:&cols]; connectorNames = (char **)malloc(rows * sizeof(char *)); numConnectors = 0; totalNameLength = 0; for(row = 0; row < rows; row++) { buttonCell = [connectorMatrix cellAt:row :0]; if([buttonCell state]) { title = [buttonCell title]; titleLength = strlen(title); *(connectorNames+numConnectors) = (char *)malloc(titleLength+1); strcpy(*(connectorNames+numConnectors), title); numConnectors++; totalNameLength = totalNameLength + titleLength; } } connectorIdString = (char *)malloc(totalNameLength + 6 * numConnectors + 1); strcpy(connectorIdString, ""); for(row = 0; row < numConnectors; row++) { connectorLine = (char *)malloc(6 + strlen(*(connectorNames+row)) +1); sprintf(connectorLine, "\tid\t%s;\n", *(connectorNames+row)); lastTab = rindex(connectorLine, '\t'); *(lastTab+1) = tolower(*(lastTab+1)); strcat(connectorIdString, connectorLine); free(connectorLine); } connectorString = (char *)malloc(totalNameLength+ 4 * numConnectors + 1); strcpy(connectorString, ""); for(row = 0; row < numConnectors; row++) { strcat(connectorString, "\""); strcat(connectorString, *(connectorNames+row)); strcat(connectorString, "\""); strcat(connectorString, ", "); } setMethodsMString = (char *)malloc(53 * numConnectors + 2 * totalNameLength + 1); strcpy(setMethodsMString,"\n"); for(row = 0; row < numConnectors; row++) { setMethodString = (char *) malloc(2 * strlen(*(connectorNames+row))+ 53); sprintf(setMethodString, "- set%s:anObject\n{\n\t%s = " "anObject;\n\treturn self;\n}\n\n", *(connectorNames+row), *(connectorNames+row)); firstTab = index(setMethodString, '\t'); *(firstTab+1) = tolower(*(firstTab+1)); strcat(setMethodsMString, setMethodString); free(setMethodString); } *rindex(setMethodsMString, '\n') = '\0'; setMethodsHString = (char *)malloc(17 * numConnectors + totalNameLength + 2); strcpy(setMethodsHString,""); for(row = 0; row < numConnectors; row++) { setMethodString = (char *) malloc(strlen(*(connectorNames+row)) + 17); sprintf(setMethodString, "- set%s:anObject;\n", *(connectorNames+row)); strcat(setMethodsHString, setMethodString); free(setMethodString); } return self; } - (BOOL)readDataFromStream:(NXStream*)stream { [scratchText readText:stream]; return YES; } - (BOOL)writeDataToStream:(NXStream*)stream { [scratchText writeText:stream]; return YES; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.