ftp.nice.ch/pub/next/developer/resources/classes/DirPanel.2.0.s.tar.gz#/DirPanel/DirPanel.m

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.