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.