This is Controller.m in view mode; [Download] [Up]
// Copyright (C) 1995 Steve Hayman
// Use is governed by the MiscKit license
#import "Controller.h"
#import <misckit/misckit.h>
#import "MiscViews.subproj/MiscIconWell.h"
#import <stdio.h>
@implementation Controller
- appDidInit:sender
{
char bundleTemplates[MAXPATHLEN+1];
FILE *p;
MiscString *cmdline = [[MiscString alloc] init];
MiscString *aFile = [[MiscString alloc] init];
/*
* Set up some defaults
*/
static NXDefaultsVector myDefaults = {
{"OpenInProjectBuilder", "YES"},
{NULL}
};
[NXApp registerDefaults:myDefaults];
templateList = [[MiscStringArray alloc] init];
[templates setDelegate:templateList];
templatePathnames = [[MiscStringArray alloc] init];
[[NXBundle mainBundle] getPath:bundleTemplates
forResource:"QuickProjectTemplates" ofType:NULL];
/*
* Run a simple command to retrieve a list of all the possible
* project templates.
* TODO - use a MiscSubprocess here (maybe - might be overkill)
*/
/*
* Use ls rather than echo just so we get output files one per line.
*/
[cmdline catFromFormat:"/bin/ls -d ~/Library/QuickProjectTemplates/* /LocalLibrary/QuickProjectTemplates/* %s/*", bundleTemplates];
p = popen([cmdline stringValue], "r");
if ( p ) {
// read filenames, add to the lists.
[aFile setStringValue:""];
while ( [aFile fgets:p keepNewline:NO] != EOF ) {
// Keep a list of full pathnames in templatePathnames;
// keep a parallel list of filenames in templateList, which
// is what's displayed in the browser.
[templatePathnames addString:[aFile stringValue]];
[templateList addString:
[[aFile fileName] stringValueAndFree]];
[aFile setStringValue:""];
}
[templates loadColumnZero];
[self showSelectedPath:templates];
pclose(p);
} else {
NXRunAlertPanel([NXApp appName],
"Couldn't make list of project templates", NULL,NULL,NULL);
}
/*
* And finally, select the Name text as a convenience.
*/
[name selectText:self];
/*
* Register to receive TIFF services. So you can use Grab to get
* an icon, which we'll make into an image and paste into the
* icon well.
*/
{
const char *returnTypes[2];
returnTypes[0] = NXTIFFPboardType;
returnTypes[1] = NULL;
[NXApp registerServicesMenuSendTypes:NULL andReturnTypes:returnTypes];
}
return self;
}
/*
* Save the icon, if there is one, to a temporary file and return
* a MiscString containing its pathname.
*/
- saveIconToTempFile
{
MiscString *filename;
NXStream *str;
if ( ! [iconWell image] )
return nil;
filename = [[MiscString alloc] init];
[filename catFromFormat:"/tmp/icon%d.tiff", getpid()];
str = NXOpenMemory(NULL, 0L, NX_READWRITE);
[[iconWell image] writeTIFF:str];
NXSaveToFile( str, [filename stringValue] );
NXCloseMemory(str, NX_FREEBUFFER);
return filename;
}
- saveAs:sender
{
id sp = [SavePanel new];
MiscString *cmd = [[MiscString alloc] init];
const char *filename;
const char *templatePath;
int pos;
MiscSubprocess *proc;
NXBundle *mainBundle = [NXBundle mainBundle];
id selectionList = [[List alloc] init];
MiscString *iconFileName;
if ( ! [name stringValue] || (strlen([name stringValue]) == 0) ) {
NXRunAlertPanel([NXApp appName],
"Please supply a name for your project.",
NULL,NULL,NULL);
return nil;
}
if ( [sp runModalForDirectory:NULL file: [name stringValue]] ) {
filename = [sp filename];
destinationFile = [MiscString newWithString:filename];
// Save the icon image - if there is one - in a file so that
// we can pass its pathname to copy_project.
iconFileName = [self saveIconToTempFile];
// Now copy the chosen project. Figure out the index of
// the selected cell, and ask the templateList for the full
// string value at that position -not just the basename
// displayed in the browser
pos = [[templates matrixInColumn:0] selectedRow];
templatePath = [templatePathnames stringAt:pos];
// copy_project template_dir dest_dir template_name appname
[cmd sprintf:"%s/copy_project %s %s %s %s %s",
[mainBundle directory],
templatePath,
[sp filename],
[templates stringValue],
[name stringValue],
iconFileName ? [iconFileName stringValue] : ""];
[iconFileName free];
/*
* Fire up a MiscSubprocess object to execute the copy command.
*/
proc = [[MiscSubprocess alloc]
init:[cmd stringValue]
withDelegate:self];
}
[cmd free];
[selectionList free];
return self;
}
/*
* This is the target of the browser. The browser shows only the
* basename of the project template you've chosen; display its full
* path as well. (Except we replace the home directory with "~" since it
* takes up less space on the screen.)
*/
- showSelectedPath:sender
{
int selection = [[sender matrixInColumn:0] selectedRow];
id templatePath = [MiscString newWithString: [templatePathnames stringAt:selection]];
[templatePath replaceHomeWithTilde]; // looks nicer. less room too.
[selectedTemplatePath
setStringValue: [templatePath stringValueAndFree]];
return self;
}
/*
* Subprocess delegate methods
*/
- subprocess:sender done:(int)status :(MiscSubprocessEndCode)code
{
MiscString *projectFile;
[sender terminate:self];
[sender free];
if ( code == Misc_Exited && status == 0 ) {
/*
* message Workspace here to open the PB.project
*/
if ( [NXApp defaultBoolValue:"OpenInProjectBuilder"] ) {
/*
* Figure out the path to the PB.project file
*/
projectFile = [destinationFile copy];
[projectFile cat:"/PB.project"];
[[[self log:"Opening project file "]
log:[projectFile stringValue]]
log:"\n"];
[[Application workspace] openFile:[projectFile stringValue]];
[projectFile free];
}
NXRunAlertPanel([NXApp appName],
"Project created succesfully.", "OK", NULL, NULL);
}
return self;
}
- subprocess:sender output:(const char *) buffer
{
[self log:buffer];
return self;
}
- subprocess:sender stderrOutput:(const char *)buffer
{
[self log:buffer];
return self;
}
- subprocess:sender error:(const char *)errorString
{
[self log:"Error: "];
[self log:errorString];
return self;
}
- log:(const char *)str
{
int len;
if ( ! processLog )
[NXApp loadNibSection:"SubprocessLog.nib" owner:self];
len = [processLog textLength];
[processLog setSel:len:len];
[processLog replaceSel:str];
[processLog scrollSelToVisible];
[[processLog window] makeKeyAndOrderFront:self];
return self;
}
/*
* Preferences handling
*/
- showPreferences:sender
{
if ( ! prefsPanel ) {
[NXApp loadNibSection:"Preferences.nib" owner:self];
[openInPBSwitch setState:
[NXApp defaultBoolValue:"OpenInProjectBuilder"]];
}
[self revert:self];
[prefsPanel makeKeyAndOrderFront:self];
return self;
}
- ok:sender
{
[NXApp setBoolDefault:"OpenInProjectBuilder" to: [openInPBSwitch state]];
return self;
}
- revert:sender
{
[openInPBSwitch setState: [NXApp defaultBoolValue:"OpenInProjectBuilder"]];
return self;
}
/*
* A couple of methods that support doing Services -> Grab
* so we can pick up a tiff and use it as our icon
*/
- validRequestorForSendType:(NXAtom)typeSent
andReturnType:(NXAtom)typeReturned
{
if ( typeSent == NULL && typeReturned == NXTIFFPboardType )
return self;
return nil;
}
- readSelectionFromPasteboard:pb
{
id image = [[NXImage alloc] initFromPasteboard:pb];
/*
* what we should do here is save the image to a temp file,
* and tell the icon well that that's the filename.
* but this is quicker for now even though not what we want.
*/
[iconWell setImage: image];
return self;
}
/*
* Some more methods that allow pasting a TIFF selection.
*/
- paste:sender
{
id pb = [Pasteboard new];
BOOL tiffFound = NO;
const NXAtom *types;
NXImage *pasteImage;
types = [pb types];
/*
* is there TIFF on the pasteboard?
*/
if ( types ) {
while ( *types ) {
if ( *types++ == NXTIFFPboardType ) {
tiffFound = YES;
break;
}
}
}
if ( ! tiffFound )
return nil;
pasteImage = [[NXImage alloc] initFromPasteboard:pb];
[iconWell setImage: pasteImage]; // don't free it. iconwell keeps it.
return self;
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.