This is DirPanel.m in view mode; [Download] [Up]
/* DirPanel * * A category of SavePanel that extends SavePanel's capabilities * to specifying directories instead of files. * * Copyright 1991, 1992 Scott Hess. This source code may be * redistributed and modified without restriction. Well, one * restriction - do not claim that you wrote it. * * Scott Hess * 12901 Upton Avenue South, #326 * Burnsville, MN 55337 * (612) 895-1208 * scott@gac.edu * shess@ssesco.com */ #import "DirPanel.h" #import <appkit/Button.h> #import <appkit/Form.h> #import <appkit/NXBrowser.h> #import <appkit/OpenPanel.h> @implementation SavePanel (DirPanel) /* This flags a real cancel. */ static BOOL notCancel=NO; /* This is where the real okButton is stored. */ static id realOkButton=nil; /* When we are masquerading as the okButton, catch setEnabled:. * Always leave the okButton enabled. */ - setEnabled:(BOOL)flag { [realOkButton setEnabled:YES]; return self; } /* All other methods are forwarded to Button. * I'm assuming that the right Button methods make it through. If * it relies on responder chains and stuff, though, I'm probably * sunk. In any case, it does seem to work, which is all I ask. */ - forward:(SEL)aSelector :(marg_list)argFrame { if( [realOkButton respondsTo:aSelector]) { return [realOkButton performv:aSelector :argFrame]; } return [self doesNotRecognize:aSelector]; } /* Call this just like runModal. */ -(int)dirPanelRunModal { int ret; /* Store the okButton target/action. */ id okt=[okButton target]; SEL oka=[okButton action]; /* Store the browser target/action. */ id browsert=[browser target]; SEL browsera=[browser action]; SEL browserda=[browser doubleAction]; /* Enable the button, and redirect it at realOk:. */ [okButton setEnabled:YES]; [okButton setTarget:self]; [okButton setAction:@selector( realOk:)]; /* Redirect the browser. */ [browser setTarget:self]; [browser setDoubleAction:@selector( realOk:)]; [browser setAction:NULL]; /* Force to reload the browser. Otherwise, it might come * up with no visible selection (the selection sometimes * scrolled out of view to the left). */ [browser loadColumnZero]; /*store away the okButton, and "become" it. */ realOkButton=okButton; okButton=self; /* Make sure we don't misfire on this. */ notCancel=NO; /* OpenPanel doesn't seem to pay attention to setRequiredFileType, * so I have to do things differently for it. Actually, I * would tend to recommend just using SavePanels, but that's * just me. * * The idea, here, is that not many people are going to * have files named *.abcdefghijklmnop, so the SavePanel * can't find any, so it can only show directories, that * you can move around in and look for stuff. Since we're * choosing directories, this is the right behaviour. */ if( [self isMemberOf:[SavePanel class]]) { [self setRequiredFileType:"abcdefghijklmnop"]; ret=[self runModal]; } else { const char *types[]={ "abcdefghijklmnop", NULL}; /* I cast to OpenPanel to remove the warning on compile. */ ret=[(OpenPanel *)self runModalForTypes:types]; } /* If SavePanel thinks we canceled, check to see if _we_ * think so, too. */ if( !ret && notCancel) { notCancel=NO; ret=YES; } /* Restore the okButton's target/action. */ okButton=realOkButton; [okButton setTarget:okt]; [okButton setAction:oka]; /* Restore the browser's original target/action. */ [browser setTarget:browsert]; [browser setAction:browsera]; [browser setDoubleAction:browserda]; return ret; } /* Handles ok's for the panel. I need to pretend to be a cancel, * for some reason. Don't ask me - it wasn't working when I didn't * do it, so I left it. */ - realOk:sender { const char *formValue=[form stringValueAt:0]; if( [sender isKindOf:[NXBrowser class]]) { /* Causes a visible "bounce" for the okButton, along with * running this action. */ return [okButton performClick:sender]; } /* If there's data in the form, then don't exit. */ if( !formValue || !*formValue) { /* Mark this as a fake Cancel. */ notCancel=YES; /* Use the ok: method to pull out any data from the form. */ [self ok:sender]; /* Use cancel: to get out of the modal loop. */ return [self cancel:sender]; } else { /* Both of these methods may draw, so flush all at once. */ [self disableFlushWindow]; /* Aquire the data from the form. */ [self ok:sender]; /* Make certain that the lastColumn's selection is visible. * Consider typing "..". Without this code, it could * ".." right off the left hand side of the browser, and * there would be no visible selection and the right hand * column would be blank. */ if( [browser numVisibleColumns]>1) { [browser scrollColumnToVisible:[browser lastColumn]-1]; } [self reenableFlushWindow]; [self flushWindowIfNeeded]; return self; } } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.