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.