{\rtf0\ansi{\fonttbl\f0\fswiss Helvetica;\f1\fmodern Courier;\f2\fnil Times-Roman;}
\paperw11760
\paperh7800
\margl120
\margr120
{\colortbl;\red0\green0\blue0;}
\pard\tx520\tx1060\tx1600\tx2120\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f0\b\i0\ulnone\fs24\fc0\cf0 #import <appkit/appkit.h>\
#import "FileWellView.h"\
#import "Query.h"\
\
@implementation FileWellView\

\b0\i\fc1\cf1 /* Class variables */
\b\i0\fc0\cf0 \
#define dNumPasteboardTypes 1\
static const char *gPasteboardTypes[dNumPasteboardTypes];\
static NXImage *gSelectionImages[N_Images];\
static const char *gImageNames[] = \{"document", "folder", "multiple"\};\
\
+ initialize\
\{\

\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f1\b0\i\fc0\cf0 /*
{{\NeXTHelpMarker342 \markername initialize;}
¬}\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f1\b0\i\ulnone\fs24\fc0\cf0  --- 
\ul MethodDescription
\ulnone \
	
\i0\ul ReturnValue:
\i\ulnone  self;\
	
\i0\ul Description:
\i\ulnone  This sets the types of Pasteboard types the\
		FileWellView class can provide as an NXDraggingSource.  It\
		also creates NXImage objects for the file selections we\
		can represent.;\
*/
\pard\tx520\tx1060\tx1600\tx2120\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f0\b\i0\fc0\cf0 \
int imageNum;\
\
	
\b0\i /* We only supply the filename of our selection representation */
\b\i0 \
	gPasteboardTypes[0] = NXFilenamePboardType;\
\
	for(imageNum = 0; imageNum < N_Images;  imageNum ++)\
	\{	
\b0\i /* Create the images for the types of files we represent */
\b\i0 \
		gSelectionImages[imageNum] = [NXImage findImageNamed:\
			gImageNames[imageNum]];\
		if( gSelectionImages[imageNum] == nil )\
			[self error: INTERNAL_SORRY method:_cmd\
				key: "Failed to create image: %s",  gImageNames[imageNum]];\
	\}\
\
	return self;\
\} 
\b0\i // End initialize
\b\i0 \
\
- setDelegate: srcDelegate\
\{\

\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f1\b0\i\fc0\cf0 /*
{{\NeXTHelpMarker1131 \markername setDelegate:;}
¬}\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f1\b0\i\ulnone\fs24\fc0\cf0  --- 
\ul MethodDescription
\ulnone \
	
\i0\ul ReturnValue:
\i\ulnone  self;\
	
\i0\ul Description:
\i\ulnone  Set our delegate to the srcDelegate. Currently this\
		is a Query object.;\
	
\i0\ul Args:
\i\ulnone \
		srcDelegate: The object which is responsible for\
			providing our pasteboard data;\
*/
\pard\tx520\tx1060\tx1600\tx2120\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f0\b\i0\fc0\cf0 \
	if( [srcDelegate respondsTo:@selector(provideSrcData:)] == NO )\
		[self error: INTERNAL_ALERT method:_cmd\
			key: "The FileWellView delegate does not respond to provideSrcData:"];\
	delegate = srcDelegate;\
\
	return self;\
\} 
\b0\i // End setDelegate:
\b\i0 \
\

\b0\i\fs28 /*\\ ---------------- NXDraggingSource Protocol Methods ---------------- \\*/
\b\i0\fs24 \
- draggedImage:(NXImage *) image beganAt:(NXPoint *) screenPoint\
\{\

\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f1\b0\i\fc0\cf0 /*
{{\NeXTHelpMarker1747 \markername draggedImage:beganAt:;}
¬}\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f1\b0\i\ulnone\fs24\fc0\cf0  --- 
\ul MethodDescription
\ulnone \
	
\i0\ul ReturnValue:
\i\ulnone  self;\
	
\i0\ul Description:
\i\ulnone  Not currently used;\
*/
\pard\tx520\tx1060\tx1600\tx2120\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f0\b\i0\fc0\cf0 \

\f1\b0\fs20 [self debug: MAX_DEBUG method:_cmd, NULL];
\f0\b\fs24 \
	return self;\
\} 
\b0\i // End draggedImage: beganAt:
\b\i0 \
\
- draggedImage:(NXImage *) image endedAt:(NXPoint *) screenPoint deposited:(BOOL) flag\
\{\

\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f1\b0\i\fc0\cf0 /*
{{\NeXTHelpMarker2009 \markername draggedImage:endedAt:deposited:;}
¬}\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f1\b0\i\ulnone\fs24\fc0\cf0  --- 
\ul MethodDescription
\ulnone \
	
\i0\ul ReturnValue:
\i\ulnone  self;\
	
\i0\ul Description:
\i\ulnone  Not currently used;\
*/
\pard\tx520\tx1060\tx1600\tx2120\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f0\b\i0\fc0\cf0 \

\f1\b0\fs20 [self debug: MAX_DEBUG method:_cmd, "deposited = %d", flag];
\f0\b\fs24 \
	return self;\
\} 
\b0\i // 
\fc1\cf1 End draggedImage: endedAt: deposited:
\b\i0\fc0\cf0 \
\
\
- (NXDragOperation) draggingSourceOperationMaskForLocal:(BOOL) flag\
\{\

\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f1\b0\i\fc0\cf0 /*
{{\NeXTHelpMarker2282 \markername draggingSourceOperationMaskForLocal:;}
¬}\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f1\b0\i\ulnone\fs24\fc0\cf0  --- 
\ul MethodDescription
\ulnone \
	
\i0\ul ReturnValue:
\i\ulnone  The dragging operation types we provide;\
	
\i0\ul Description:
\i\ulnone  Returns value which is the result of oring\
		the various dragging operation types we provide. If we have a\
		delegate, we also set our provideData flag to YES, indicating that\
		our 
\b pasteboard:provideData:
\b0  method will try to obtain the pasteboard\
		data.;\
	
\i0\ul Args:
\i\ulnone \
		flag: whether or not the current destination is in our app;\
*/
\pard\tx520\tx1060\tx1600\tx2120\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f0\b\i0\fc0\cf0 \
NXDragOperation ourOps;\

\f1\b0\fs20 [self debug: MAX_DEBUG method:_cmd, "local = %d", flag];
\f0\b\fs24 \
\
	if( delegate == nil )\
		ourOps = NX_DragOperationNone;\
	else\
	\{\
		ourOps = NX_DragOperationLink | NX_DragOperationCopy | NX_DragOperationGeneric;\
		provideData = YES;\
	\}\
\
	return ourOps;\
\} 
\b0\i // End draggingSourceOperationMaskForLocal:
\b\i0 \
\
- mouseDown:(NXEvent *) theEvent\
\{\

\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f1\b0\i\fc0\cf0 /*
{{\NeXTHelpMarker3057 \markername mouseDown:;}
¬}\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f1\b0\i\ulnone\fs24\fc0\cf0  --- 
\ul MethodDescription
\ulnone \
	
\i0\ul ReturnValue:
\i\ulnone  self if currentImage is non-nil, else super's\
		value of 
\b mouseDown:
\b0 ;\
	
\i0\ul Description:
\i\ulnone  This is where the dragging is initiated by invoking\
		the 
\b dragImage:
\b0 ... method. If this is a double click event, we\
		ask send an 
\b openInWorkspace:
\b0  message to our delegate.;\
	
\i0\ul Args:
\i\ulnone \
		theEvent: The mouse down event which triggered this method;\
*/
\pard\tx520\tx1060\tx1600\tx2120\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f0\b\i0\fc0\cf0 \
Pasteboard *thePboard;\
NXPoint imageOrg = \{0, 0\};\
\
	if( currentImage == nil )\
		return [super mouseDown: theEvent];\
\
	
\b0\i /* Check for a double click event */
\b\i0 \
	if( theEvent->data.mouse.click > 1 )\
	\{\

\f1\b0\fs20 [self debug: MAX_DEBUG method:_cmd, "double click, sending openInWorkspace: to %p", delegate];
\f0\b\fs24 \
		return [delegate openInWorkspace: self];\
	\}\
\
	
\b0\i /* Prevent default window ordering so that dragging the selection image\
		from the interface does not bring our window to the front */
\b\i0 \
	[NXApp preventWindowOrdering];\
\
	
\b0\i /* Prepare the pasteboard for a drag operation.  We don't place the\
		data on the pasteboard until we are sent a pasteboard:provideData:\
		message. */
\b\i0 \
	provideData = NO;\
	thePboard = [Pasteboard newName: NXDragPboard];\
	[thePboard declareTypes: gPasteboardTypes num: dNumPasteboardTypes\
		owner: self];\
\
	
\b0\i /* Begin the dragging session */
\b\i0 \
	[self dragImage: currentImage at: &imageOrg offset: NULL\
		event: theEvent  pasteboard:thePboard source: self\
		slideBack: YES];\
\
	return self;\
\} 
\b0\i // End mouseDown:
\b\i0 \
\
 - (BOOL) acceptsFirstMouse\
\{\

\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f1\b0\i\fc0\cf0 /*
{{\NeXTHelpMarker4467 \markername acceptsFirstMouse;}
¬}\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f1\b0\i\ulnone\fs24\fc0\cf0  --- 
\ul MethodDescription
\ulnone \
	
\i0\ul ReturnValue:
\i\ulnone  YES;\
	
\i0\ul Description:
\i\ulnone  Since we want a user to be able to drag our\
		current image without having to make our interface\
		window key, we override this method to return YES;\
*/
\pard\tx520\tx1060\tx1600\tx2120\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f0\b\i0\fc0\cf0 \
	return YES;\
\}\
\
- (BOOL) shouldDelayWindowOrderingForEvent:(NXEvent *) theEvent\
\{\

\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f1\b0\i\fc0\cf0 /*
{{\NeXTHelpMarker4761 \markername shouldDelayWindowOrderingForEvent:;}
¬}\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f1\b0\i\ulnone\fs24\fc0\cf0  --- 
\ul MethodDescription
\ulnone \
	
\i0\ul ReturnValue:
\i\ulnone  YES;\
	
\i0\ul Description:
\i\ulnone  Since we want a user to be able to drag our\
		current image without having to make our interface\
		window key, we override this method to return YES;\
	
\i0\ul Args:
\i\ulnone \
		theEvent: The mouse down event which started the dragging;\
*/
\pard\tx520\tx1060\tx1600\tx2120\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f0\b\i0\fc0\cf0 \
	return YES;\
\} 
\b0\i // End shouldDelayWindowOrderingForEvent:
\b\i0 \
\

\b0\i\fs28\fc1\cf1 /*\\ ---------------------- Drawing Methods ---------------------- \\*/
\b\i0\fs24\fc0\cf0 \
- clear\
\{\

\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f1\b0\i\fc0\cf0 /*
{{\NeXTHelpMarker5179 \markername clear;}
¬}\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f1\b0\i\ulnone\fs24\fc0\cf0  --- 
\ul MethodDescription
\ulnone \
	
\i0\ul ReturnValue:
\i\ulnone  self;\
	
\i0\ul Description:
\i\ulnone  Sets currentImage to nil and invokes display;\

\pard\tx520\tx1060\tx1600\tx2120\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\fc1\cf1 */
\f0\b\i0\fc0\cf0 \
	currentImage = nil;\
	[self display];\
\
	return self;\
\} 
\b0\i // End clear
\b\i0 \
\
- drawSelf:(const NXRect *) rects :(int) rectCount\
\{	\

\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f1\b0\i\fc0\cf0 /*
{{\NeXTHelpMarker5411 \markername drawSelf::;}
¬}\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f1\b0\i\ulnone\fs24\fc0\cf0  --- 
\ul MethodDescription
\ulnone \
	
\i0\ul ReturnValue:
\i\ulnone  self;\
	
\i0\ul Description:
\i\ulnone  The usual override to draw our contents. We\
		simply composite the current image to our bounds origin.\
		This assumes that the images our the same size as our\
		bounds.;\
	
\i0\ul Args:
\i\ulnone \
		rects: The array of NXRects defining the area needing updating;\
		rectCount: The number of NXRects in rects;\
*/
\pard\tx520\tx1060\tx1600\tx2120\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f0\b\i0\fc0\cf0 \
	PSsetgray(NX_LTGRAY);\
	NXRectFill(&bounds);\
	if( currentImage != nil )\
		[currentImage composite: NX_SOVER toPoint: &bounds.origin];\
\
	return self;\
\} 
\b0\i // End drawSelf::
\b\i0 \
\
- showImage:(SelectionType) type\
\{\

\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f1\b0\i\fc0\cf0 /*
{{\NeXTHelpMarker5967 \markername showImage:;}
¬}\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f1\b0\i\ulnone\fs24\fc0\cf0  --- 
\ul MethodDescription
\ulnone \
	
\i0\ul ReturnValue:
\i\ulnone  self;\
	
\i0\ul Description:
\i\ulnone  Set our currentImage variable to one of the\
		NXImages in 
\fc1\cf1 gSelectionImages if type is valid, otherwise\
		currentImage is set to nil
\fc0\cf0 ;\
	
\i0\ul Args:
\i\ulnone \
		type: The in
\fc1\cf1 dex into gSelectionImages of t
\fc0\cf0 he image;\
*/
\pard\tx520\tx1060\tx1600\tx2120\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f0\b\i0\fc0\cf0 \
	switch( type )\
	\{\
		case eDocumentSelection:\
		case eFolderSelection:\
		case eMultipleSelection:\
			currentImage = gSelectionImages[type];\
			break;\
		default:\
			currentImage = nil;\
	\}\
	if( [s
\fc1\cf1 elf 
\f2\fs28\fc0\cf0 isAutodisplay
\f0\fs24\fc1\cf1 ] == YES )\
		[se
\fc0\cf0 lf display];\
	else\
		[self 
\f2\fs28 setNeedsDisplay
\f0\fs24 : YES];\
\
	return self;\
\} 
\b0\i // End showImage:
\b\i0 \
\

\b0\i\fs28\fc1\cf1 /*\\ ---------------------- Pasteboard Methods ---------------------- \\*/
\b\i0\fs24\fc0\cf0 \
- pasteboard: sender provideData:(NXAtom) type\
\{\

\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f1\b0\i\fc0\cf0 /*
{{\NeXTHelpMarker6659 \markername pasteboard:provideData:;}
¬}\pard\tx180\tx360\tx540\tx720\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f1\b0\i\ulnone\fs24\fc0\cf0  --- 
\ul MethodDescription
\ulnone \
	
\i0\ul ReturnValue:
\i\ulnone  self;\
	
\i0\ul Description:
\i\ulnone  This method retrieves the filename data from\
		our delegate and writes it to the pasteboard;\
	
\i0\ul Args:
\i\ulnone \
		sender: the Pasteboard in need of data;\
		type: The type of data requested;\
*/
\pard\tx520\tx1060\tx1600\tx2120\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f0\b\i0\fc0\cf0 \
NXStream *dataStream;\
static char *failedData = "'***_FAILED_TO_PROVIDE_DATA_***'";\
\
	if( provideData == NO )\
	\{	
\b0\i /* A mouse click intiated a dragging session but our\
			draggingSourceOperationMaskForLocal method was never called,\
			indicating that the icon never reached a NXDraggingDestination */
\b\i0 \
		[sender writeType: type data: failedData length: strlen(failedData)];\
		return self;\
	\}\
\
	if( type == NXFilenamePboardType )\
	\{	
\b0\i /* Get the data from our delegate */\
/* --- Error ---\
	This really does not work very well because the NXDestination usually asks for the \
	data before one can drag the image over the point where the image should be\
	dropped. We need some way to indicate the data we will provide, but not actually\
	have to do so from within the 
\b mouseDown:
\b0  method that started the dragging.*/
\b\i0 \
		dataStream = [delegate provideSrcData: type];\
		if( dataStream == NULL )\
			[sender writeType: type data: failedData length: strlen(failedData)];\
		else\
		\{\
			[sender writeType: type fromStream: dataStream];\
			NXCloseMemory(dataStream, NX_FREEBUFFER);\
		\}\
	\}\
\
	return self;\
\} 
\b0\i // End pasteboard: provideData:
\b\i0 \
\
@end\

\b0\i /* RCS Information:\
	$Author: me $;\
	$Date: 94/01/08 14:40:18 $;\
	$Source: /usr1/me/NeXTSrc/Archie/RCS/FileWellView.m,v $;\
	$Revision: 1.1 $;\
	$Log:	FileWellView.m,v $
Revision 1.1  94/01/08  14:40:18  me
Check point of 2.09a version.
Revision 1.4  93/03/29  01:56:33  meModified pasteboard data method to place a _FAILED_TO_PROVIDE_DATA_ string on the pasteboard if the delegate failes to provide the data.\
Revision 1.3  93/03/01  22:47:28  meFixed problem of write an empty string to the pasteboard with a length of 1 which would crash that workspace.\
Revision 1.2  93/02/26  03:12:29  meAdded debug: message to indicate when a double click causes FileWellView to message its delegate Query.\
Revision 1.1  93/02/23  02:10:16  meVersion 2.01a of the project.;\
*/\

}
