This is TSIconViewShelfItem.m in view mode; [Download] [Up]
/* TSIconViewShelfItem.m created by tsengel on Fri 15-Aug-1997 */
#import "TSIconViewShelfItem.h"
#import "File.h"
@implementation TSIconViewShelfItem
- (id)initWithContentsOfFile:(NSString *)aString
{
self = [super initWithContentsOfFile:aString];
if( !self) return nil;
// <<HACK>> evil...
[NSBundle loadNibNamed:@"IconViewShelf" owner:self];
[view setClassToHold:@"File"];
[view addListener:[File class]];
[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];
if( !aString )
[[view cellAtRow:0 column:0] setDelegate:[File fileForPath:NSHomeDirectory()]];
return self;
}
- (void)revert:(id)sender
{
[super revert:sender];
if( !contentLoaded )
{
// Ok...now this is evil mean cheating... actually the problem is taht we fill the matrix before it has een resized
// to the full windows size. This causes some trouble if the matrix has not enough elemets to fill in.
// The currentl "fix" is the make the matrix quite large in the NIB... but this needs
// a real fix.
// E.g. like catching the"DiSwapIn" notification etc.
[self updateShelfContent];
contentLoaded = YES;
}
}
- (void)updateShelfContent
/*"
Takes the set path and tries to put the content into the shelf matrix...which is our view
"*/
{
int columns, rows;
id contentDict = [NSDictionary dictionaryWithContentsOfFile:[[self path] stringByAppendingPathComponent:@"Info.plist"]];
id itemEnum = [[contentDict objectForKey:@"Files"] objectEnumerator];
id nextFilePath;
id aFile;
id aCell;
for( rows = 0; rows<[view numberOfRows]; rows++ )
{
for( columns = 0; columns<[view numberOfColumns]; columns++ )
{
nextFilePath = [itemEnum nextObject];
if( nextFilePath && ![nextFilePath isEqual:@""] )
{
// We will make loaded items "sticky" becasue they are propably inteded to stay
// on the shelf forever... command dragging will move them away.
// THis behavior should be "adjustable" for the entire shelf via prefs or that like.
aFile = [File fileForPath:nextFilePath];
aCell = [view cellAtRow:rows column:columns];
[aCell setLocked:YES];
[aCell setDelegate:aFile];
}
}
}
// The content did change..so lets rememrb that so that we can save it...
[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 !
// NSLog( @"Shelf content did change due to drag.." );
[self setContentDidChange:YES];
}
- (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;
// NSLog( @"Trying to select cell...");
if( _pendingClickEvent == -1 ) return;
if( _mouseDraggedAfterClick )
{
_mouseDraggedAfterClick = NO;
return;
}
// NSLog( @"Succeeded to select cell...");
aPath = [[aCell delegate] path];
if( [[NSUserDefaults standardUserDefaults] boolForKey:@"UseWorkspaceThreads"] )
[NSThread detachNewThreadSelector:@selector(_detachedFileSelect:)
toTarget:self
withObject:aPath];
else
[self performSelector:@selector(_detachedFileSelect:)
withObject:aPath
afterDelay:0.5];
}
- (void)_detachedFileSelect:(id)thePath
{
// The subpool is needed if we are a new thread...
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..
[NSApp deactivate];
[[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(_detachedAppLaunch:)
toTarget:self
withObject:aPath];
else
[self performSelector:@selector(_detachedAppLaunch:)
withObject:aPath
afterDelay:0.5];
}
else
{
if( [[NSUserDefaults standardUserDefaults] boolForKey:@"UseWorkspaceThreads"] )
[NSThread detachNewThreadSelector:@selector(_detachedFileOpen:)
toTarget:self
withObject:aPath];
else
[self performSelector:@selector(_detachedFileOpen:)
withObject:aPath
afterDelay:0.5];
}
}
- (void)_detachedAppLaunch:(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)_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 ourFileArray = [NSMutableArray new];
id ourFileDict = [NSMutableDictionary new];
int rows, columns;
id aPath;
[super save];
// Now save all the file refs.
for( rows = 0; rows<[view numberOfRows]; rows++ )
{
for( columns = 0; columns<[view numberOfColumns]; columns++ )
{
aPath = [[[view cellAtRow:rows column:columns] delegate] path];
if( !aPath ) aPath = @"";
[ourFileArray addObject:aPath];
}
}
basePath = [basePath stringByAppendingPathComponent:@"Info.plist"];
[ourFileDict setObject:@"IconViewShelf" forKey:@"ShelfType"];
[ourFileDict setObject:ourFileArray forKey:@"Files"];
[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.