ftp.nice.ch/Attic/openStep/tools/workspace/TheShelf.0.3.3.sd.tgz#/TheShelf.0.3.3.sd/Source/ApplicationTrayShelf.bproj/TSApplicationTrayShelfItem.m

This is TSApplicationTrayShelfItem.m in view mode; [Download] [Up]

/* TSApplicationTrayShelfItem.m created by tsengel on Fri 15-Aug-1997 */

#import "TSApplicationTrayShelfItem.h"

#import "File.h"
#import "TSWorkspace.h"

@implementation TSApplicationTrayShelfItem

/*
This class is a hack and will go away in the future...its dependancy on another bundle is a hacky solution to get this done fast..
*/
- (id)initWithContentsOfFile:(NSString *)aString
{
    id		aPath;
    id		ourBundle;
    id		fileClass;

    self = [super initWithContentsOfFile:aString];
    if( !self) return nil;

    // <<HACK>> evil...we depend on the other bundle .. the IconBundle !!

    aPath = [[NSBundle mainBundle] pathForResource:@"IconViewShelf" ofType:@"bundle"];
    ourBundle = [NSBundle bundleWithPath:aPath];

    [NSBundle loadNibNamed:@"ApplicationTrayShelf" owner:self];

    // Lets set a somewhat useful shelf title...

    [self setTitle:@"Processes"];

    // <<HACK>> ???? Hmm.... somehow this code does not work as expected ???

    fileClass = [ourBundle classNamed:@"File"];
    if( !fileClass ) fileClass = [File class];
    [view addListener:fileClass];
    [view setClassToHold:@"File"];
    [view setTarget:self];
    [view setAction:@selector(selectShelfEntry:)];
    [view setDoubleAction:@selector(openShelfEntry:)];

    // We will add ourself as a listener so that we find out whne things change on the shelf. 

    [view addListener:self];

    // And some notificatons please... ok..the revert: part is a hack...but then...who cares.

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(revert:)
                                                 name:@"ProcessesListChanged"
                                               object:nil];
    return self;
}

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];

    [super dealloc];
}

- (void)revert:(id)sender
{
    [super revert:sender];

    [self updateShelfContent];
}

- (void)updateShelfContent
/*"
   Takes the set path and tries to put the content into the shelf matrix...which is our view
"*/
{
    int		columns, rows;
    id	itemEnum = [[[TSWorkspace sharedWorkspace] runningApplications] objectEnumerator];
    id 	nextFilePath;
    id	aFile;
    id	aCell;

    for( rows = 0; rows<[view numberOfRows]; rows++ )
    {
        for( columns = 0; columns<[view numberOfColumns]; columns++ )
        {
            nextFilePath = [itemEnum nextObject];
            aFile = nil;
            if( nextFilePath )
                aFile = [File fileForPath:nextFilePath];

            aCell = [view cellAtRow:rows column:columns];
            [aCell setReallyLocked:YES];
            [aCell setDelegate:aFile];
            // [aCell setDraggable:NO];
            // [aCell setEditable:NO];
        }
    }
    // The content did change..so lets rememrb that so that we can save it...
    // but since there is currently nothing to save... lets not worry right now..
    // [self setContentDidChange:YES];
}

- (unsigned int)shelf:sender willDrag:objectToPaste from:(id <NSDraggingInfo>) source;
{
    // Just be sure we don't handle it as another click..it really is a drag operation !

    // NSLog( @"Markd the mouse drag op..." );
    _mouseDraggedAfterClick = YES;
    return NSDragOperationAll;
}

- (void)shelf:sender dragWillComplete:(id <NSDraggingInfo>) source;
{
    // Just be sure we don't handle it as another click !

    // NOTE.. this should never happen in this shelf !!

    // NSLog( @"Shelf content did change due to drag.." );
}

- (void)selectShelfEntry:(id)sender
{
    // Ok..this return here is evil...but single-doubleclick needs to be handled properly with a delayed perform
    // so right now this is disabled.

    _pendingClickEvent = [[NSApp currentEvent] eventNumber];

    [self performSelector:@selector(reallySelectCell:)
               withObject:[view selectedCell]
               afterDelay:0.8];
}

 - (void)reallySelectCell:aCell
 {
     // Let's check if this click is still wanted..perhaps we already
     // performed the double click or dragged some object after the first mouseDown.

    id	aPath;

    if( _pendingClickEvent == -1 ) return;

    if( _mouseDraggedAfterClick )
    {
        _mouseDraggedAfterClick = NO;
        return;
    }

    aPath = [[aCell delegate] path];
    if( [[NSUserDefaults standardUserDefaults] boolForKey:@"UseWorkspaceThreads"] )
        [NSThread detachNewThreadSelector:@selector(_detachedAppActivation:)
                                 toTarget:self
                               withObject:aPath];
    else
        [self performSelector:@selector(_detachedAppActivation:)
                   withObject:aPath
                   afterDelay:0.5];
}

- (void)_detachedFileSelect:(id)thePath
{
    id		threadPool = [NSAutoreleasePool new];

    // <<HACK>> This is "bad!!!" since this "/" causes the workspace to open yet
    // another browser window. But the @"" does not work and causes an exception on 4.2...bad..

    [[NSWorkspace sharedWorkspace] selectFile:thePath
                     inFileViewerRootedAtPath:@"/"];
    [threadPool release];
}

- (void)openShelfEntry:(id)sender
{
    id	cell;
    id	aPath;

    // Sicne this event is handled now..reset the marker.

    _pendingClickEvent = -1;
    cell = [view selectedCell];
    aPath = [[cell delegate] path];

    if( [[aPath pathExtension] isEqual:@"app"] )
    {
       if( [[NSUserDefaults standardUserDefaults] boolForKey:@"UseWorkspaceThreads"] )
            [NSThread detachNewThreadSelector:@selector(_detachedAppFullActivation:)
                                     toTarget:self
                                   withObject:aPath];
        else
            [self performSelector:@selector(_detachedAppFullActivation:)
                       withObject:aPath
                       afterDelay:0.5];
    }
    else
    {
        // Ok..here this should never ever happen.. no non APP files allowed..

        if( [[NSUserDefaults standardUserDefaults] boolForKey:@"UseWorkspaceThreads"] )
            [NSThread detachNewThreadSelector:@selector(_detachedFileOpen:)
                                     toTarget:self
                                   withObject:aPath];
        else
            [self performSelector:@selector(_detachedFileOpen:)
                       withObject:aPath
                       afterDelay:0.5];
    }
}

- (void)_detachedAppActivation:(id)thePath
{
    // The subpool is needed if we are a new thread...

    id		threadPool = [NSAutoreleasePool new];

    [NSApp deactivate];
    [[NSWorkspace sharedWorkspace] launchApplication:thePath];

    // Using the launchApplication:thePath showIcon:YES autolaunch:NO method does not work properly ???

    [threadPool release];
}

- (void)_detachedAppFullActivation:(id)thePath
{
    // The subpool is needed if we are a new thread...

    id		threadPool = [NSAutoreleasePool new];

    [[NSWorkspace sharedWorkspace] hideOtherApplications];
    [NSApp deactivate];
    [[NSWorkspace sharedWorkspace] launchApplication:thePath];

    // Using the launchApplication:thePath showIcon:YES autolaunch:NO method does not work properly ???

    [threadPool release];
}

- (void)_detachedFileOpen:(id)thePath
{
    // The subpool is needed if we are a new thread...

    id		threadPool = [NSAutoreleasePool new];
    [NSApp deactivate];
    [[NSWorkspace sharedWorkspace] openFile:thePath];
    [threadPool release];
}

- (void)save
{
    id		basePath = [self path];
    id		ourFileDict = [NSMutableDictionary new];

    [super save];

    basePath = [basePath stringByAppendingPathComponent:@"Info.plist"];

    [ourFileDict setObject:@"ApplicationTrayShelf" forKey:@"ShelfType"];
    [ourFileDict writeToFile:basePath atomically:YES];
}

@end

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.