home *** CD-ROM | disk | FTP | other *** search
- #import <math.h>
- #import "Fiend.h"
- #import "Dock.h"
- #import "IconDragView.h"
- #import "ShelfView.h"
- #import "DockMgrView.h"
- #import "Controller.h"
- #import "FiendWraps.h"
-
- #import <appkit/appkit.h>
- #import <mach/mach.h>
- #import <bsd/sys/file.h>
-
-
- static id destroySound;
- int mouseMoved(NXPoint *o, int n, int mask);
-
- typedef enum { Unknown,
- SameDeviceOperation,
- WriteNotAllowed,
- CrossDeviceOperation,
- ApplicationDirectory } DragStatus;
-
-
- @implementation IconDragView : IconView
-
- + initialize
- {
- destroySound = [Sound findSoundFor:"Destroy"];
- return self;
- }
-
- - initFrame:(const NXRect *)newFrame image:anImage data:(const void *)someData
- andLength:(unsigned int) newLength useSize:(BOOL)sizeValid onDock:(BOOL)dockFlag
- {
- const char *const types[1] = {NXFilenamePboardType};
-
- [self registerForDraggedTypes:types count:1];
- [super initFrame:newFrame image:anImage data:someData andLength:newLength
- useSize:sizeValid onDock:dockFlag];
-
- altImage = nil;
- selected = NO;
- dockDrag = NO;
-
- return self;
- }
-
-
- - free
- {
- [altImage free];
- return [super free];
- }
-
- - sizeTo:(NXCoord) width :(NXCoord) height
- {
- NXSize aSize;
-
- [super sizeTo:width :height];
- if (altImage) {
- [image getSize:&aSize];
- [altImage setSize:&aSize];
- }
- return self;
- }
-
- - drawSelf:(const NXRect *) rects :(int) rectCount
- {
- id tImage = image;
-
- if (altImage)
- image = altImage;
- [super drawSelf:rects :rectCount];
- image = tImage;
-
- return self;
- }
-
-
- - image
- {
- return image;
- }
-
-
- - getData:(void **) aPtr andLength:(unsigned int *) aLength
- {
- *aPtr = data;
- *aLength = length;
- return self;
- }
-
- - handleMouseMoved:(NXEvent *)saveEvent imagePt:(NXPoint *)imgPt offsetPt:(NXPoint *)offPt
- {
- NXPoint imageLoc;
- NXPoint mousePoint = saveEvent->location;
- Pasteboard *pboard = [Pasteboard newName:NXDragPboard];
-
- if (onDock)
- [dockMgrView stopScanTimer];
-
- if (!onDock)
- [superview setDragView:self onEvent:saveEvent withOffset:offPt atLocation:imgPt];
- else if (saveEvent->flags & NX_ALTERNATEMASK) {
- NXImage *dragImage = [IconView getImageForPath:data fileIcon:YES zone:[self zone]];
-
- [pboard declareTypes:&NXFilenamePboardType num:1 owner:nil];
- [pboard writeType:NXFilenamePboardType data:data length:strlen(data)];
- [self dragImage:dragImage at:&frame.origin offset:offPt
- event:saveEvent pasteboard:pboard source:dockMgrView slideBack:NO];
- [dragImage free];
- }
- else if (1 /*!sticky*/) {
- const char *types[] = {FIEND_PBTYPE};
- NXImage *dragImage = [[NXImage allocFromZone:[self zone]] initSize:&frame.size];
-
- [pboard declareTypes:types num:1 owner:nil];
- [pboard writeType:FIEND_PBTYPE data:data length:strlen(data)];
-
- [self getImagePoint:&imageLoc andHilitePoint:NULL];
- if ([dragImage lockFocus]) {
- PScomposite(0.0, 0.0, NX_WIDTH(&frame), NX_HEIGHT(&frame),
- [window gState], 0.0, 0.0, NX_COPY);
- [dragImage unlockFocus];
- }
-
- [dockMgrView setDragView:self andOffset:&mousePoint];
- [[self setGhost:YES] display];
- NXPing();
-
- dockDrag = YES;
- [self dragImage:dragImage at:&frame.origin offset:offPt
- event:saveEvent pasteboard:pboard source:dockMgrView slideBack:NO];
- [dragImage free];
- dockDrag = NO;
-
- [[self setGhost:NO] display];
- NXPing();
- }
- else if (sticky) {
- NXRunAlertPanel([NXApp appName],
- "Can't delete sticky icons!",
- NULL, NULL, NULL);
- NXBeep();
- }
-
- if (onDock)
- [dockMgrView startScanTimer];
-
- return self;
- }
-
- static void
- getDockLoc(NXPoint *p, NXSize *size)
- {
- char string[100];
- const char *ret;
-
- p->x = p->y = -1.0;
- if (size->height != ORIG_SCREEN_HEIGHT) {
- sprintf(string, "DockOriginYForHt%d", (int)size->height);
- ret = NXGetDefaultValue("Workspace", string);
- if (ret)
- p->y = atoi(ret);
- sprintf(string, "DockOriginXForHt%d", (int)size->height);
- ret = NXGetDefaultValue("Workspace", string);
- if (ret)
- p->x = atoi(ret);
- }
- else {
- ret = NXGetDefaultValue("Workspace", "DockOriginY");
- if (ret)
- p->y = atoi(ret);
- ret = NXGetDefaultValue("Workspace", "DockOriginX");
- if (ret)
- p->x = atoi(ret);
- }
- if (p->x < 0.0)
- p->x = size->width - 67.0;
- if (p->y < 0.0)
- p->y = size->height - 64.0;
- }
-
- - (BOOL)handleSingleClick:(NXEvent *)e
- {
- int newStat;
- NXPoint imageLoc;
- NXPoint upperRight;
- BOOL delivered = NO;
- BOOL alt = (e->flags & NX_ALTERNATEMASK) ? YES : NO;
- BOOL shift = (e->flags & NX_SHIFTMASK) ? YES : NO;
- BOOL control = (e->flags & NX_CONTROLMASK) ? YES : NO;
- BOOL command = (e->flags & NX_COMMANDMASK) ? YES : NO;
- BOOL noFlags = (!command && !shift && !control && !alt);
- BOOL justCommand = (command && !alt && !shift && !control);
- BOOL useSound = !strcmp(NXGetDefaultValue([NXApp appName], USE_SOUND), "YES");
- BOOL demandDockCommand = !strcmp(NXGetDefaultValue([NXApp appName], ENAB_DCLCK), "NO");
- BOOL demandShelfCommand = !strcmp(NXGetDefaultValue([NXApp appName], ENAB_SCLCK), "NO");
- struct stat buf;
- const char *path = (const char *)data;
-
- if (onDock) {
- if (ghost) {
- ghost = NO;
- [self display];
- }
- [[NXApp delegate] deselectShelf];
- }
- else
- [[NXApp delegate] deselectDock];
-
- if ((onDock && ((noFlags && !demandDockCommand) || (justCommand && demandDockCommand))) ||
- (!onDock && ((noFlags && !demandShelfCommand) || (justCommand && demandShelfCommand)))) {
- [self getImagePoint:&imageLoc andHilitePoint:NULL];
- [self convertPoint:&imageLoc toView:nil];
- [window convertBaseToScreen:&imageLoc];
-
- getDockLoc(&upperRight, &screenSize);
- if (onDock)
- [[dockMgrView currentDock] select:NO all:self];
- else
- [superview deselectAll:self];
-
- [self setState:YES];
- [[Application workspace] slideImage:image from:&imageLoc to:&upperRight];
- delivered = [[Application workspace] selectFile:path inFileViewerRootedAt:""];
- if (delivered)
- [[Application workspace] launchApplication:"WM"];
- [self setState:NO];
-
- if (!(autoScan && isLaunched) && ((newStat = stat(path, &buf)) != statReturn)) {
- statReturn = newStat;
- [self restoreIconImage];
- }
- }
- else if (control) {
- if (!onDock) {
- [superview perform:@selector(deleteView:)
- with:self afterDelay:0.0 cancelPrevious:YES];
- [superview perform:@selector(writeShelf)
- with:nil afterDelay:1000.0 cancelPrevious:YES];
- [[NXApp delegate] perform:@selector(updateMenus)
- with:nil afterDelay:1000.0 cancelPrevious:NO];
- delivered = YES;
- if (useSound)
- [destroySound play:self];
- }
- else {
- if (!sticky) {
- [dockMgrView deleteView:self];
- delivered = YES;
- }
- else {
- NXLogError("%s is flagged as persistent - can't delete", path);
- NXBeep();
- }
- }
- }
- else if (shift && command && onDock) {
- [dockMgrView inspectIcon:self];
- delivered = YES;
- }
- else if (shift) {
- [NXApp unhide:self];
- [self setState:!selected];
- delivered = YES;
- }
- else if (alt && onDock) {
- if (!(autoScan && isLaunched) && ((newStat = stat(path, &buf)) != statReturn)) {
- statReturn = newStat;
- [self restoreIconImage];
- }
- [dockMgrView app:dockMgrView applicationDidLaunch:path];
- delivered = YES;
- }
- else {
- if (onDock)
- [[dockMgrView currentDock] select:NO all:self];
- else
- [superview deselectAll:self];
- delivered = YES;
- }
-
- return delivered;
- }
-
- - delayedActivate
- {
- if (appCtxt > 0)
- fiendUnhideContext(appCtxt, 1, 1, 0);
-
- return self;
- }
-
- - (BOOL)handleDoubleClick:(NXEvent *)e
- {
- int newStat;
- NXPoint imageLoc;
- NXPoint upperRight;
- struct stat buf;
- BOOL delivered = NO;
- BOOL alt = (e->flags & NX_ALTERNATEMASK) ? YES : NO;
- BOOL cmd = (e->flags & NX_COMMANDMASK) ? YES : NO;
- const char *path = (const char *)data;
- float delay = 1000.0 * atof(NXGetDefaultValue([NXApp appName], ACTIVE_DELAY));
- BOOL closePostLaunch = !strcmp(NXGetDefaultValue([NXApp appName], CLOSE_PSTLNCH), "YES");
-
- if (!autoScan && ((newStat = stat(path, &buf)) != statReturn)) {
- statReturn = newStat;
- [self restoreIconImage];
- }
- if (!isApp) {
- [self getImagePoint:&imageLoc andHilitePoint:NULL];
- [self convertPoint:&imageLoc toView:nil];
- [window convertBaseToScreen:&imageLoc];
-
- getDockLoc(&upperRight, &screenSize);
- [[Application workspace] slideImage:image from:&imageLoc to:&upperRight];
- delivered = [[Application workspace] openFile:path];
- }
- else if (cmd && isLaunched) {
- fiendUnhideContext(appCtxt, 1, 1, 1);
- delivered = YES;
- }
- else if (!alt) {
- if (!isLaunched) {
- if (!onDock)
- [self setState:YES];
- else
- [self setGhost:YES];
-
- [self display];
- NXPing();
-
- if (onDock) {
- [self setFiendLaunch:YES];
- [dockMgrView launch:path autolaunch:NO];
- }
- else
- [[Application workspace] launchApplication:path];
-
- if (!onDock) {
- [self setState:NO];
- [self display];
- }
- }
- else
- fiendUnhideContext(appCtxt, 1, 1, 0);
- delivered = YES;
- }
- else if (!onDock && alt) {
- delivered = [[Application workspace] openFile:path];
- [self perform:@selector(delayedActivate) with:nil afterDelay:delay cancelPrevious:YES];
- }
- if (onDock && closePostLaunch && delivered)
- [dockMgrView setShowDock:NO];
-
- return delivered;
- }
-
- - mouseDown:(NXEvent *) e
- {
- int savedMask;
- NXPoint mousePoint;
- NXPoint offset;
- NXEvent newEvent;
- NXEvent savedEvent;
- BOOL delivered = NO;
- int mask = NX_LMOUSEDRAGGEDMASK|NX_LMOUSEUPMASK;
-
- savedEvent = *e;
- mousePoint = e->location;
- savedMask = [window addToEventMask:mask];
- if (mouseMoved(&mousePoint, 2, mask)) {
- offset.x = mousePoint.x - e->location.x;
- offset.y = mousePoint.y - e->location.y;
- [self handleMouseMoved:&savedEvent imagePt:&imagePoint offsetPt:&offset];
- }
- else {
- if (![NXApp peekNextEvent:NX_LMOUSEDOWNMASK into:&newEvent
- waitFor:0.2 threshold:NX_MODALRESPTHRESHOLD]) {
- delivered = [self handleSingleClick:&savedEvent];
- }
- else {
- (void)[NXApp getNextEvent:NX_LMOUSEDOWNMASK];
- delivered = [self handleDoubleClick:&savedEvent];
- }
- if (!delivered)
- NXBeep();
- }
-
- [[NXApp delegate] updateMenus];
- [window setEventMask:savedMask];
- return self;
- }
-
-
- - (NXDragOperation)draggingSourceOperationMaskForLocal:(BOOL)isLocal
- {
- return NX_DragOperationAll;
- }
-
- - (BOOL) acceptsFirstMouse
- {
- return YES;
- }
-
-
- - (BOOL) acceptsFirstResponder
- {
- return NO;
- }
-
- - getOpenImageForDirectory:(const char *) dirname
- {
- struct stat st;
- char buf[MAXPATHLEN+1];
- id newImage = nil;
-
- strncpy(buf, dirname, sizeof(buf));
- strncat(buf, "/", sizeof(buf));
- strncat(buf, OPEN_DIR_ICON_FILE, sizeof(buf));
- if (access(buf, R_OK) == 0) {
- newImage = [[NXImage allocFromZone:[self zone]] initFromFile:buf];
- if (newImage)
- return newImage;
- }
-
- if (stat(dirname, &st) >= 0 && st.st_ino == 2) {
- NXSize size;
- [image getSize:&size];
- newImage = [[NXImage allocFromZone:[self zone]] initSize:&size];
- if ([newImage lockFocus]) {
- NXPoint zeroPoint = {0,0};
- id highlight = [NXImage allocFromZone:[self zone]];
- char buf[MAXPATHLEN+1];
- NXBundle *bundle;
-
- bundle = [NXBundle bundleForClass:[self class]];
- if ([bundle getPath:buf forResource:OPEN_HIGHLIGHT ofType:"tiff"]) {
- [[[highlight initFromFile:buf] setScalable:YES] setSize:&size];
- [image composite:NX_COPY toPoint:&zeroPoint];
- [highlight composite:NX_SOVER toPoint:&zeroPoint];
- [newImage unlockFocus];
- return newImage;
- }
- }
- }
-
- if (access(DEFAULT_OPEN_DIR_FILE, R_OK) == 0)
- newImage = [[NXImage allocFromZone:[self zone]] initFromFile:DEFAULT_OPEN_DIR_FILE];
-
- if (newImage != nil)
- return newImage;
- else
- return image;
- }
-
-
- /*
- * Figure out the various parameters of the drag.
- */
- - (DragStatus) dragStatusForPath:(char *)dragPath
- {
- char *destinationPath;
- unsigned int junk;
- struct stat st;
-
- [self getData:(void **) &destinationPath andLength:&junk];
-
- if (!strcmp(destinationPath, dragPath))
- return WriteNotAllowed;
-
- if (IS_APP_PATH(destinationPath)) {
- dragDestType = NXApplicationFileType;
- return ApplicationDirectory;
- }
-
- if (stat(destinationPath, &st) < 0 || (st.st_mode & S_IFMT) != S_IFDIR)
- return WriteNotAllowed;
- if (access(destinationPath, W_OK|X_OK) < 0)
- return WriteNotAllowed;
-
- dragDestType = NXDirectoryFileType;
- if (stat(destinationPath, &st) < 0)
- return Unknown;
- else {
- dev_t destDev = st.st_dev;
- ino_t destIno = st.st_ino;
-
- if (lstat(dragPath, &st) >= 0 &&
- st.st_dev == destDev && destIno == st.st_ino)
- return WriteNotAllowed;
- }
-
- if (stat(destinationPath, &st) >= 0) {
- dev_t destinationDevice = st.st_dev;
- if (lstat(dragPath, &st) >= 0)
- if (st.st_dev != destinationDevice)
- return CrossDeviceOperation;
- else
- return SameDeviceOperation;
- }
-
- return Unknown;
- }
-
-
- - (NXDragOperation) dragOperationForContext:(id <NXDraggingInfo>) dragInfo
- {
- unsigned int junk;
- char *dragPath;
- char *nextPath;
- BOOL first = YES;
- NXDragOperation op = NX_DragOperationNone;
- id pb = [Pasteboard newName:NXDragPboard];
- NXDragOperation maskOp = [dragInfo draggingSourceOperationMask];
-
- [pb types];
- [pb readType:NXFilenamePboardType data:&dragPath length:&junk];
-
- nextPath = dragPath;
- do {
- char path[MAXPATHLEN+1];
- NXDragOperation thisOp = maskOp;
-
- strncpy(path, nextPath, MAXPATHLEN);
- if (index(path, '\t'))
- *index(path, '\t') = '\0';
-
- switch ([self dragStatusForPath:path]) {
- case WriteNotAllowed:
- case Unknown:
- thisOp = NX_DragOperationNone;
- break;
-
- case ApplicationDirectory:
- if (maskOp == NX_DragOperationGeneric)
- thisOp = NX_DragOperationGeneric;
- else
- thisOp = NX_DragOperationNone;
- break;
-
- case CrossDeviceOperation:
- if (maskOp & NX_DragOperationCopy) {
- thisOp = NX_DragOperationCopy;
- break;
- }
-
- case SameDeviceOperation:
- if (maskOp & NX_DragOperationGeneric) {
- thisOp = NX_DragOperationGeneric;
- break;
- }
-
- default:
- break;
- }
-
- if (first) {
- op = thisOp;
- first = NO;
- }
- else {
- if (op != thisOp) {
- [pb deallocatePasteboardData:dragPath length:junk];
- return NX_DragOperationNone;
- }
- }
-
- nextPath = index(nextPath, '\t');
- if (nextPath == NULL)
- break;
- else
- nextPath++;
-
- } while (1);
-
- [pb deallocatePasteboardData:dragPath length:junk];
-
- return op;
- }
-
-
- - (NXDragOperation)draggingEntered:(id <NXDraggingInfo>)sender
- {
- lastDragOp = [self dragOperationForContext:sender];
- if (lastDragOp == NX_DragOperationPrivate || lastDragOp == NX_DragOperationNone)
- return NX_DragOperationNone;
- else if (dragDestType == NXDirectoryFileType) {
- NXSize imageSize;
-
- altImage = [self getOpenImageForDirectory:data];
-
- [image getSize:&imageSize];
- [altImage setScalable:YES];
- [altImage setSize:&imageSize];
-
- [self display];
- }
-
- return lastDragOp;
- }
-
-
- - (NXDragOperation)draggingUpdated:(id <NXDraggingInfo>)sender
- {
- lastDragOp = [self dragOperationForContext:sender];
- return lastDragOp;
- }
-
-
- - draggingExited:(id <NXDraggingInfo>)sender
- {
- [altImage free];
- altImage = nil;
- [self display];
- [window flushWindow];
- return self;
- }
-
-
- - (BOOL) prepareForDragOperation:sender
- {
- return YES;
- }
-
- - (BOOL) performDragOperation:(id <NXDraggingInfo>)sender
- {
- return YES;
- }
-
-
- - concludeDragOperation:(id <NXDraggingInfo>)sender
- {
- char *path;
- char *dragPath;
- const char *wsmOp;
- unsigned int pbLength;
- id workspace = [Application workspace];
- id pb = [Pasteboard newName:NXDragPboard];
-
- [pb types];
- [pb readType:NXFilenamePboardType data:&dragPath length:&pbLength];
-
- if (dragDestType == NXDirectoryFileType) {
- switch (lastDragOp) {
- case NX_DragOperationGeneric:
- wsmOp = WSM_MOVE_OPERATION;
- break;
- case NX_DragOperationLink:
- wsmOp = WSM_LINK_OPERATION;
- break;
- case NX_DragOperationCopy:
- wsmOp = WSM_COPY_OPERATION;
- break;
- default:
- [pb deallocatePasteboardData:dragPath length:pbLength];
- return NO;
- }
- [workspace performFileOperation:wsmOp source:"/" destination:data
- files:dragPath options:NULL];
- }
- else if (dragDestType == NXApplicationFileType && lastDragOp == NX_DragOperationGeneric) {
- path = strtok(dragPath, "\t");
- while(path && strlen(path)) {
- [workspace openFile:path withApplication:data andDeactivate:NO];
- path = strtok(NULL, "\t");
- }
- }
- [pb deallocatePasteboardData:dragPath length:pbLength];
-
- return [self draggingExited:sender];
- }
-
- @end
-
-
- /*
- * Returns true if mouse is dragged more than n pixels from 'o',
- * false if the mouse button is lifted. If the mouse button is
- * lifted, the mouseUp event is not consumed.
- */
- int
- mouseMoved(NXPoint *o, int n, int mask)
- {
- NXEvent e;
- NXPoint p;
- float dx, dy;
-
- do {
- [NXApp peekNextEvent:mask into:&e waitFor:0x7fffffff
- threshold:NX_MODALRESPTHRESHOLD];
- p = e.location;
- if (e.type == NX_LMOUSEUP)
- break;
-
- (void) [NXApp getNextEvent:mask]; /* throw it away */
- dx = abs(p.x - o->x);
- dy = abs(p.y - o->y);
-
- } while ((dy < (float) n) && (dx < (float) n));
- *o = p;
-
- return e.type != NX_LMOUSEUP;
- }
-
-