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.