home *** CD-ROM | disk | FTP | other *** search
-
- #import "Controller.h"
- #import "Document.h"
- #import "InspectorManager.h"
- #import "defs.h"
- #import "util.h"
-
- @implementation Controller
-
- /* ==== init section ==== */
- + initialize
- {
- static NXDefaultsVector appDefaults=
- { { "DEBUGFILE", "~/debugfile" },
- { "WindowSize", "400 300" },
- { "NewEmptyDocument", "YES" },
- { (char *)NULL},
- };
- NXRegisterDefaults([NXApp appName], appDefaults);
- return self;
- }
-
- - init
- { [super init];
- controllerZone=NXCreateZone(vm_page_size, vm_page_size, NO);
- return self;
- }
-
- - appDidInit:sender
- {
- id w;
-
- docList=[[List allocFromZone:controllerZone] init];
-
- w=[accessoryView window];
- [accessoryView removeFromSuperview];
- [w free];
-
- if(!fileName && BoolValueForDefault("NewEmptyDocument"))
- [self newDocument:nil];
-
- return self;
- }
-
- /* ==== document management section ==== */
-
- - openFile:sender
- {
- static const char *const Filetypes[]=EXTENSION_STRINGS;
- const char *name=NULL;
-
- if(sender)
- { if ([[OpenPanel new] runModalForTypes: Filetypes]==NO)
- return (self);
- else
- if(!(name=[[OpenPanel new] filename]))
- { fprintf(stderr,"Failed to find file: %s\n",
- [[OpenPanel new] filename]);
- return self;
- }
- }
- else name=fileName; //opened through the workspace
-
- [self openDocument:name];
-
- /* fileName is handed off to the document object */
- if(fileName)
- { free((char *)fileName);
- fileName=NULL;
- }
- return self;
- }
-
- - createDocumentObject:sender
- {
- NXZone *zone;
- Document *doc;
- static int documentTag=0;
-
- zone=NXCreateZone(vm_page_size*1024, vm_page_size, YES);
-
- /* allocate a new document object */
- doc=[[Document alloc] init];
-
- if(!doc)
- { internalError("Could not allocate document object");
- return nil;
- }
-
- /* this section opens the document file */
- [doc setTag:documentTag++];
- [NXApp perform:@selector(updateWindows) with:nil
- afterDelay:1 cancelPrevious:YES];
-
- /* put the object on the list of documents */
- [docList addObject:doc];
- return doc;
- }
-
- - openDocument:(const char *)aPath
- {
- id doc;
-
- if(!aPath) return nil;
-
- if((doc=[self findDocWithPath:aPath])!=nil)
- { [[doc window] makeKeyAndOrderFront:nil];
- return nil;
- }
-
- doc=[self createDocumentObject:self];
-
- if(![doc openDocFile:aPath])
- { [[NXApp delegate] perform:@selector(freeDoc:) with:doc
- afterDelay:1 cancelPrevious:YES];
- return nil;
- }
-
- return doc;
- }
-
- - newDocument:sender
- {
- char buf[BUFSIZE]="";
- id new;
- static int untitledCount=0;
-
- do { if(untitledCount)
- { sprintf(buf,"%s/UNTITLED%d",NXHomeDirectory(), untitledCount);
- }
- else sprintf(buf,"%s/UNTITLED",NXHomeDirectory());
- untitledCount++;
- } while([self findDocWithPath:buf]);
- new=[self createDocumentObject:self];
- [new setupNewDoc:buf];
- return self;
- }
-
- - save:sender;
- {
- const char *name=[currentDoc documentName];
- if(!name) return self;
-
- if(!strncmp(name,"UNTITLED",8))
- [self saveAs:sender];
- else [currentDoc saveDocument];
- return self;
- }
-
- - saveAs:sender
- {
- const char *file;
- char name[1024];
- id savePanel;
-
- if(!currentDoc) return self;
- savePanel=[SavePanel new];
- [savePanel setAccessoryView:nil];
- if ([savePanel runModal])
- file = [[SavePanel new] filename];
- else return self;
-
- if (file)
- { strcpy(name,file);
- insertExt(name, DOC_EXTENSION);
- [currentDoc saveDocumentAs:name];
- }
-
- return self;
- }
-
- - saveTo:sender;
- {
- const char *file;
- char name[1024];
- id savePanel;
-
- if(!currentDoc) return self;
- savePanel=[SavePanel new];
-
- [savePanel setAccessoryView:accessoryView];
- if ([savePanel runModal])
- file = [[SavePanel new] filename];
- else return self;
-
- if (file)
- { /* insert the needed extension if not there */
- strcpy(name,file);
- [currentDoc saveDocumentAs:name];
- }
- return self;
- }
-
- - saveAll:sender
- { return self;
- }
-
- - revert:sender
- {
- id doc=currentDoc;
-
- if(!doc) return self;
-
- /* clear the inspector */
- currentDoc=nil;
- [inspectorManager updateInspector:self];
- [docList removeObject:doc];
-
- if(!strcmp([doc documentName],"UNTITLED"))
- { NXRunAlertPanel("Revert",
- "Document does not have a name, cannot revert...",NULL,NULL,NULL);
- return self;
- }
- /* this will set the new doc to be the currentdoc */
- currentDoc=[self openDocument:[doc documentPath]];
-
- /* this will free the old one */
- [[doc window] setDocEdited:NO];
- [[doc window] performClose:self];
-
- return self;
- }
-
- - close:sender
- { if(!currentDoc) return self;
- return [[currentDoc window] performClose:nil];
- }
-
- - freeDoc:aDoc
- {
- if(!aDoc) return nil;
-
- [docList removeObject:aDoc];
-
- if(currentDoc==aDoc) currentDoc=nil;
- [NXApp delayedFree:aDoc];
-
- [NXApp perform:@selector(updateWindows) with:nil
- afterDelay:100 cancelPrevious:YES];
-
- return self;
- }
-
- - findDocWithPath:(const char *)aPath
- {
- id *l;
- int i,count;
- const char *p;
-
- count=[docList count];
- l=NX_ADDRESS(docList);
- for(i=0;i<count;i++)
- { p=[l[i] documentPath];
- if(p && !strcmp(aPath,p)) return l[i];
- }
- return nil;
- }
-
- - findDocWithTag:(int)aTag
- {
- id *l;
- int i,count;
-
- count=[docList count];
- l=NX_ADDRESS(docList);
- for(i=0;i<count;i++)
- { if([l[i] tag]==aTag) return l[i];
- }
- return nil;
- }
-
- /* ==== panels ==== */
-
- - getPrefsPanel:sender
- {
- if(!prefManager)
- [NXApp loadNibSection:"PrefPanel.nib" owner:self
- withNames:NO fromZone:controllerZone];
- [prefManager getPanelWithScreen:0];
- return self;
- }
-
- - getInspectorPanel:sender
- {
- /* called from the menu */
- [self getInspectorPanelWithScreen:0];
- return self;
- }
-
- - (BOOL)getInspectorPanelWithScreen:(int)aScreen
- {
- /* called from the keyboard */
- if(aScreen<0 || aScreen>1) return NO;
- if(!inspectorManager)
- [NXApp loadNibSection:"InspectorPanel.nib" owner:self
- withNames:NO fromZone:controllerZone];
- [inspectorManager getPanelWithScreen:aScreen];
- return YES;
- }
-
- - getInfoPanel:sender
- {
- if(!infoPanel)
- [NXApp loadNibSection:"InfoPanel.nib" owner:self
- withNames:NO fromZone:controllerZone];
- [infoPanel makeKeyAndOrderFront:nil];
- return self;
- }
-
- /* ==== access to instance variables ==== */
-
- /* the current document always point to the document object
- corresponding to the current window
- */
-
- - setCurrentDoc:aDoc
- { currentDoc=aDoc;
- return self;
- }
-
- - currentDoc
- { return currentDoc;
- }
-
-
- /* ==== application delegate methods ==== */
-
- - (BOOL)appAcceptsAnotherFile:sender
- {
- return YES;
- }
-
- - (int)appOpenFile:(const char *)path type:(const char *)type
- {
-
- if(strncmp(type, DOC_EXTENSION, strlen(DOC_EXTENSION))) return NO;
- fileName=NXCopyStringBufferFromZone(path, controllerZone);
-
- [self perform:@selector(openFile:) with:nil afterDelay:1
- cancelPrevious: NO];
- return YES;
- }
-
- - appWillTerminate:sender
- {
- int i,count=[docList count];
- BOOL needsWarning=NO;
- id doc,*l=NX_ADDRESS(docList);
-
- TRY_AGAIN:
- doc=currentDoc;
- for(i=0;i<count;i++)
- { if([[l[i] window] isDocEdited]) needsWarning=YES;
- }
- if(needsWarning)
- { switch(NXRunAlertPanel("Quit",
- "There are edited documents",
- "Review Unsaved","Quit Anyway","Cancel"))
- { case NX_ALERTDEFAULT: // Review Unsaved
-
- for(i=0;i<count;i++)
- { if([[l[i] window] isDocEdited])
- { switch(NXRunAlertPanel("Review Unsaved",
- "Save changes to %s","Save","Don't save",
- "Cancel",[l[i] documentPath]))
- { case NX_ALERTDEFAULT: //Save
- currentDoc=l[i];
- [[l[i] window] orderFront:nil];
- [self save:self];
- currentDoc=doc;
- break;
- case NX_ALERTALTERNATE: //Don't save
- break;
- case NX_ALERTOTHER: //Cancel
- goto TRY_AGAIN;
- }
- }
- }
- case NX_ALERTALTERNATE: //Quit Anyway
- break;
- case NX_ALERTOTHER: //Cancel
- return nil;
- }
- }
-
- return self;
- }
-
- @end
-