home *** CD-ROM | disk | FTP | other *** search
- // 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
-