This is SFODragDropText.m in view mode; [Download] [Up]
#import "SFODragDropText.h" #import <appkit/appkit.h> @implementation SFODragDropText - awakeFromNib { NXAtom supportedTypes[11] = {NXFilenamePboardType, NXFileContentsPboardType, NXSoundPboardType, NXPostScriptPboardType, NXTIFFPboardType, NXColorPboardType, NXFontPboardType, NXRulerPboardType, NXRTFPboardType, NXAsciiPboardType, NULL}; [self registerForDraggedTypes:supportedTypes count:10]; return self; } /********************************************/ /* add file contents dragging */ /********************************************/ - (NXDragOperation)draggingUpdated:(id <NXDraggingInfo>)sender { // Check for self-drags if ([sender draggingSource] == self) return NX_DragOperationNone; return [super draggingUpdated:sender]; } - (int)positionForCell:theCell { int pos,k,N; NXRun *curr; if (theCell == nil) return -1; pos=0; N = theRuns->chunk.used/sizeof(NXRun); curr = theRuns->runs; for (k=0; k < N; k++) { if (curr->info == theCell) return pos; pos += curr->chars; curr++; } return -1; } - writeCell:theCell toPasteboard:pboard types:(NXAtom *)types { int numTypes = 0; NXSelPt start, end; int cellPos; NXStream *memStream; Text *rtfd; NXRTFDError errno; char path[MAXPATHLEN+1]; while (types && types[numTypes++]); cellPos = [self positionForCell:theCell]; if (cellPos == -1) return nil; [pboard declareTypes:types num:numTypes-1 owner:nil]; start = sp0; end = spN; [self setSel:cellPos :cellPos+1]; memStream = NXOpenMemory(NULL, 0, NX_READWRITE); [self writeRTFDSelectionTo:memStream]; NXSeek(memStream, 0, NX_FROMSTART); rtfd = [[Text alloc] init]; [[NXBundle bundleForClass:[SFODragDropText class]] getPath:path forResource:"Empty.rtfd" ofType:NULL]; [rtfd openRTFDFrom:path]; [rtfd setMonoFont:NO]; [rtfd setGraphicsImportEnabled:YES]; if ([rtfd readRTFDFrom:memStream]) if (errno = [rtfd saveRTFDTo:"/tmp/nt0815.rtfd" removeBackup:NO errorHandler:nil] != NX_RTFDErrorNone) { NXRunAlertPanel("Save RTFD", "Could not save to file %s; error %i." , "Sorry!", NULL, NULL , "/tmp/nt0815.rtfd", errno); } [rtfd free]; NXCloseMemory(memStream, NX_FREEBUFFER); sprintf(path, "/tmp/nt0815.rtfd/%s", [theCell stringValue]); [pboard writeType:NXFilenamePboardType data:path length:strlen(path)+1]; [self setSel:start.cp :end.cp]; return self; } @end @implementation NXGraphicCell(NetTalkAdditions) - (NXDragOperation)draggingSourceOperationMaskForLocal:(BOOL)isLocal { return (isLocal ? NX_DragOperationNone : NX_DragOperationCopy); } #define mask (NX_LMOUSEUPMASK|NX_LMOUSEDRAGGEDMASK) - (BOOL)trackMouse:(NXEvent *)theEvent inRect:(const NXRect *)cellFrame ofView:controlView { id dragPasteboard; NXAtom supportedTypes[] = {NXFilenamePboardType, NULL}; NXPoint offset, mLoc; NXRect tracker; NXEvent *nextEvent, saveEvent; NXImage *dragImage; char *filenameChars; int filenameLength; BOOL inside, editableFlag, shouldLoop; int oldMask; if (![controlView respondsTo:@selector(writeCell:toPasteboard:types:)]) return NO; if (theEvent->data.mouse.click == 2) { dragPasteboard = [Pasteboard newName:NXDragPboard]; [controlView writeCell:self toPasteboard:dragPasteboard types:supportedTypes]; [dragPasteboard readType:NXFilenamePboardType data:&filenameChars length:&filenameLength]; [[Application workspace] openFile:filenameChars]; [dragPasteboard free]; return YES; } if (theEvent->type == NX_LMOUSEDOWN) { oldMask = [[controlView window] addToEventMask:NX_LMOUSEDRAGGEDMASK]; saveEvent = *theEvent; tracker = *cellFrame; shouldLoop = YES; while (shouldLoop) { nextEvent = [NXApp getNextEvent:mask]; mLoc = nextEvent->location; [controlView convertPoint:&mLoc fromView:nil]; inside = [controlView mouse:&mLoc inRect:&tracker]; if (!inside) { NXSize imgSize; NXPoint imgLoc; editableFlag = [controlView isEditable]; [controlView setEditable:NO]; dragPasteboard = [Pasteboard newName:NXDragPboard]; [controlView writeCell:self toPasteboard:dragPasteboard types:supportedTypes]; [dragPasteboard readType:NXFilenamePboardType data:&filenameChars length:&filenameLength]; dragImage = [[Application workspace] getIconForFile:filenameChars]; [dragImage getSize:&imgSize]; imgLoc = saveEvent.location; [controlView convertPoint:&imgLoc fromView:nil]; imgLoc.x -= imgSize.width/2; imgLoc.y += imgSize.height/2; offset.x = nextEvent->location.x - saveEvent.location.x; offset.y = nextEvent->location.y - saveEvent.location.y; [controlView dragImage:dragImage at:&imgLoc offset:&offset event:&saveEvent pasteboard:dragPasteboard source:self slideBack:YES]; [dragImage free]; [controlView setEditable:editableFlag]; shouldLoop = NO; } if (nextEvent->type == NX_LMOUSEUP) shouldLoop = NO; // mouse up outside rects. } [[controlView window] setEventMask:oldMask]; return YES; } return NO; //[super trackMouse:theEvent inRect:cellFrame ofView:controlView]; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.