home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Nebula
/
nebula.bin
/
SourceCode
/
Classes
/
DirPanel
/
DirPanel.m
< prev
next >
Wrap
Text File
|
1992-07-09
|
5KB
|
176 lines
/* 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