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.