home *** CD-ROM | disk | FTP | other *** search
- /*
- File: DragDrp.cpp
-
- Contains: Implementation of ODDragAndDrop
-
- Owned by: Douglas Hill
-
- Copyright: © 1994 - 1996 by Apple Computer, Inc., all rights reserved.
-
- Change History (most recent first):
-
- <18> 8/13/96 DM 1376080: use TempDelayBentoFatalError to
- ensure old flag value is restored
- <17> 7/18/96 DH Task: Self-embedding causes crash. Fixed
- exception handling in drag receive handler
- so return value of Drop is propogated
- correctly.
- <16> 7/11/96 DH 1365986 1.1GM: Crash when drag fails and
- another drag is attempted. Fixed many stale
- object references.
- <15> 6/26/96 DH #1358088: Subframes allow self-embedding.
- This was a part of a more general case of
- nested self-embedding. Fixed so that the
- checks happen at drag-tracking time
- correctly. See also new recipe for marking
- frames as part of a drag.
- <14> 6/21/96 DH 1340739: 1.0.xp: Ctl-drag of content to
- non-od destination does not remove
- original.
- 1340966: 1.0.x: Avoiding undo when content
- dragged to non-OpenDoc target. 1340739:
- 1.0.xp: Ctl-drag of content to non-od
- destination does not remove original.
- 1353507: 1.0.x: Dragging Scrapbook OpenDoc
- clipping to document can cause crash. Added
- support for reading clipping files (see
- ODDragAndDropEnterHandler).
- <13> 5/31/96 jpa T10012: Overhauled IsOpenDocDocument. Set
- correct creator of files/promises created.
- <12> 5/24/96 jpa 1246074: SOM_CATCH --> SOM_TRY..SOM_ENDTRY
- <11> 5/13/96 DH 1332488 - 1.0.x:User break dragging Edition
- file into an OpenDoc window.
- 1305572 - 1.1MRD:[Cyberdog]Dragging
- multiple items *really* slow.
- 1314704 - 1.0.x: Enourmous performance hit
- when dragging numerous items over windows.
- <10> 5/1/96 JA 1314704: Create only one mem container
- (_fMemItemContainer) for all dragged-in
- non-Bento files.
- <9> .04.1996 NP 1330731: Don't use stationery property
- anymore.
- <8> 4/16/96 DH Fixed InWindow to ignore a null container.
- <7> 4/9/96 DH 1308248: 1.0.2 Drag of no-part to trash
- rejected. Used string resource for no-part
- category instead of hard-coding it. Also
- made filename of file in Trash when you
- drop Nopart into the trash not be garbled.
- <6> 4/8/96 DH 1338112: 1.0.2? Drag Hiliting Problems
- <4> 3/29/96 DM 1296171: delay fatal Bento container errors
- when inside drag manager
- <3> 3/15/96 VL 1302780: Use GetFacetUnderPointForDrag
- instead of GetFacetUnderPoint so that we
- can drop within selection.
- <2> 3/15/96 DH 287259 - 1.0.2 Don't get back what I put in
- the scrapbook. Now writes out a memory
- container to applications that it reloads
- if it is found from Drag and Drop. Also
- compatible with Clipboard container type.
- 1293781 - 1.0.2 DragWithin called out of
- order. Fixed ODDragAndDropInWindow so that
- it doesn't call DragLeave on the Containing
- part unless the embedded part returns True
- from DragEnter.
-
- To Do:
- In Progress:
-
- */
-
- #ifndef _ALTPOINT_
- #include "AltPoint.h" // Use C++ savvy ODPPoint and ODPRect
- #endif
-
- #define ODDragAndDrop_Class_Source
- #define VARIABLE_MACROS
- #include <DragDrp.xih>
-
- #ifndef SOM_ODDragItemIterator_xh
- #include <DgItmIt.xh>
- #endif
-
- #ifndef _DRAGPRIV_
- #include <DragPriv.h>
- #endif
-
- #ifndef _STORRSRC_
- #include <StorRsrc.h>
- #endif
-
- #ifndef SOM_Module_OpenDoc_StdProps_defined
- #include <StdProps.xh>
- #endif
-
- #ifndef SOM_Module_OpenDoc_StdTypes_defined
- #include <StdTypes.xh>
- #endif
-
- #ifndef SOM_ODSession_xh
- #include <ODSessn.xh>
- #endif
-
- #ifndef SOM_ODStorageSystem_xh
- #include <ODStor.xh>
- #endif
-
- #ifndef SOM_ODContainer_xh
- #include <ODCtr.xh>
- #endif
-
- #ifndef SOM_ODDocument_xh
- #include <Document.xh>
- #endif
-
- #ifndef SOM_ODDraft_xh
- #include <Draft.xh>
- #endif
-
- #ifndef SOM_ODFrame_xh
- #include <Frame.xh>
- #endif
-
- #ifndef SOM_ODFacet_xh
- #include <Facet.xh>
- #endif
-
- #ifndef SOM_ODWindow_xh
- #include <Window.xh>
- #endif
-
- #ifndef SOM_ODWindowState_xh
- #include <WinStat.xh>
- #endif
-
- #ifndef SOM_ODPart_xh
- #include <Part.xh>
- #endif
-
- #ifndef SOM_ODTransform_xh
- #include <Trnsform.xh>
- #endif
-
- #ifndef SOM_ODTranslation_xh
- #include <Translt.xh>
- #endif
-
- #ifndef _ODMEMORY_
- #include "ODMemory.h"
- #endif
-
- #ifndef _ODNew_
- #include "ODNew.h"
- #endif
-
- #ifndef _EXCEPT_
- #include "Except.h"
- #endif
-
- #ifndef _LINKLIST_
- #include "LinkList.h"
- #endif
-
- #ifndef SOM_ODStorageUnitView_xh
- #include <SUView.xh>
- #endif
-
- #ifndef _BENTOSUPPRESS_
- #include "BentoSuppress.h"
- #endif
-
- #ifndef _STORDEF_
- #include "StorDef.h"
- #endif
-
- #ifndef SOM_CMStorageUnit_xh
- #include <CMSU.xh>
- #endif
-
- #ifndef _PLFMFILE_
- #include <PlfmFile.h>
- #endif
-
- #ifndef _CONSTDEF_
- #include "ConstDef.h"
- #endif
-
- #ifndef _PASCLSTR_
- #include <PasclStr.h>
- #endif
-
- #ifndef SOM_Module_OpenDoc_StdDefs_defined
- #include "StdDefs.xh"
- #endif
-
- #ifndef _LINKDLGS_
- #include "LinkDlgs.h"
- #endif
-
- #ifndef __MEMORY__
- #include <Memory.h>
- #endif
-
- #ifndef __GESTALTEQU__
- #include <GestaltEqu.h>
- #endif
-
- #ifndef __TOOLUTILS__
- #include <ToolUtils.h>
- #endif
-
- #ifndef __ERRORS__
- #include <Errors.h>
- #endif
-
- #ifndef __SCRIPT__
- #include <Script.h>
- #endif
-
- #ifndef __PACKAGES__
- #include <Packages.h>
- #endif
-
- #ifndef __APPLEEVENTS__
- #include <AppleEvents.h>
- #endif
-
- #ifndef _ISOSTR_
- #include <ISOStr.h>
- #endif
-
- #ifndef __ALIASES__
- #include <Aliases.h>
- #endif
-
- #ifndef __FOLDERS__
- #include <Folders.h>
- #endif
-
- #ifndef _BARRAY_
- #include <BArray.h>
- #endif
-
- #ifndef SOM_ODNameSpaceManager_xh
- #include <NmSpcMg.xh>
- #endif
-
- #ifndef SOM_ODValueNameSpace_xh
- #include <ValueNS.xh>
- #endif
-
- #ifndef _TEMPOBJ_
- #include <TempObj.h>
- #endif
-
- #ifndef _STORUTIL_
- #include "StorUtil.h"
- #endif
-
- #include <string.h>
-
- #ifndef _ODDEBUG_
- #include "ODDebug.h"
- #endif
-
- #ifndef _NMSPCUTL_
- #include <NmSpcUtl.h>
- #endif
-
- #ifndef _STDTYPIO_
- #include <StdTypIO.h>
- #endif
-
- #ifndef __DIALOGS__
- #include <Dialogs.h>
- #endif
-
- #ifndef _INFOUTIL_
- #include <InfoUtil.h>
- #endif
-
- #ifndef __ICONS__
- #include <Icons.h>
- #endif
-
- #ifndef __FINDER__
- #include <Finder.h>
- #endif
-
- #ifndef _POUTILS_
- #include <POUtils.h>
- #endif
-
- #ifndef _OPENHASH_
- #include <OpenHash.h>
- #endif
-
- #ifndef _ITEXT_
- #include <IText.h>
- #endif
-
- #ifndef _USERSRCM_
- #include <UseRsrcM.h>
- #endif
-
- #ifndef _DLOGUTIL_
- #include <DlogUtil.h>
- #endif
-
- #ifndef _DRGDPDEF_
- #include "DrgDpDef.h"
- #endif
-
- #ifndef __DIALOGS__
- #include <Dialogs.h>
- #endif
-
- #ifndef _CTYPE
- #include <ctype.h>
- #endif
-
- static FSSpec gTmpFileFSSpec;
- static FSSpec gTargetFSSpec;
- static boolean gIsResolvingPromise = kODFalse;
-
- //==============================================================================
- // Prototyping
- //==============================================================================
-
- extern ODBoolean gODBentoFatalErrorHasOccurred; // SessHdr.cpp
- extern ODBoolean gODDelayBentoFatalError; // SessHdr.cpp
- extern ODBoolean gODSuppressBentoFatalError; // SessHdr.cpp
- extern void ODBentoFatalError(ODBoolean allowSuppress); // SessHdr.cpp
-
- static pascal OSErr MyDragTrackingHandler(
- short message,
- WindowPtr theWindow,
- void* handlerRefCon,
- ODPlatformDragReference theDrag);
-
- static pascal OSErr MyReceiveDropHandler(
- WindowPtr theWindow,
- void* handlerRefCon,
- ODPlatformDragReference theDrag);
-
- static pascal OSErr MySendDataProc(
- FlavorType theType,
- void* refCon,
- ItemReference theItem,
- ODPlatformDragReference theDrag);
-
- static OSErr ODPascal ReplaceFileAEHandler(
- const AppleEvent* replaceFileEvent,
- AppleEvent* reply,
- long refCon);
-
- static void RespecifyToTempFolder(PlatformFile* file);
- static OSErr CreateReplaceFileEvent(Environment* ev, AppleEvent* replaceFileEvent, ODSession* session, ProcessSerialNumber* psn);
- static OSErr SetupReplaceFileEvent(Environment* ev, AppleEvent* replaceFileEvent, FSSpec* sourceFileSpec, FSSpec* destFileSpec);
- static OSErr SendReplaceFileEvent(AppleEvent* replaceFileEvent, ProcessSerialNumber* psn);
- static OSErr DisposeReplaceFileEvent(AppleEvent* replaceFileEvent);
- static ODBoolean DragItemHasFlavor(ODPlatformDragReference theDrag, ItemReference itemID, OSType theType);
- static OSErr CloneIntoFile(Environment* ev, ODDragItem* theDragItem, FSSpec dropFSSpec);
- static void CloneIntoFlavor(Environment* ev, ODDragAndDrop* dad, ODDragItem* theDragItem,
- ODPlatformDragReference theDrag, ItemReference theItem, FlavorType theType,
- FSSpec dropFSSpec);
- static boolean MakeUniqueFilename( Environment *ev, ODSession* session, ODStorageUnit *su, FSSpec *spec );
- static OSType GetStorageUnitOSType( Environment *ev, ODStorageUnit *su );
- static OSErr CopyToDragItemInChunks(Environment* ev,
- FlavorType theType,
- ItemReference theItem,
- ODPlatformDragReference theDrag,
- ODDragItem* theDragItem);
- static OSErr CopyFromDragItemInChunks(Environment* ev,
- FlavorType theType,
- ItemReference theItem,
- ODPlatformDragReference theDrag,
- ODStorageUnitView* destSUView);
-
- static OSErr CopyMemContainerToDragItemInChunks(Environment* ev,
- ODSession* theSession,
- FlavorType theType,
- ItemReference theItem,
- ODPlatformDragReference theDrag,
- ODDragItem* theDragItem);
-
- static ODHandle CloneToTempMemContainer( Environment* ev, ODMemDragItem* tempDItem, ODSession* theSession );
- static void SetFinderInfo(Environment* ev, ODStorageUnit* su, PlatformFile* file);
- static void SetIconFamily(Environment* ev, ODStorageUnit* fromSU, PlatformFile* file);
- static OSErr GetDropFSSpec(ODPlatformDragReference theDrag, FSSpec& dropFSSpec);
- static boolean IsTrashFolder(FSSpec dropFSSpec);
- static boolean IsFrontProcess();
- static ODBoolean IsOpenDocClipping( HFSFlavor* hfsFlavor);
- static ODHandle ReadClippingFileOpenDocData( HFSFlavor* hfsFlavor );
- static ODBoolean IsNestedSelfEmbedding( ODDragAndDrop *somSelf, Environment *ev, ODFrame* destFrame );
-
- #ifdef ODDebug_DragAndDrop
-
- #ifndef SOM_ODStorageUnitCursor_xh
- #include <SUCursor.xh>
- #endif
-
- void PrintDragReference(ODPlatformDragReference dragRef, char* header);
- void PrintStorageUnit(Environment* ev, ODStorageUnit* su, char* header);
- #endif
-
- #pragma segment ODDragAndDrop
-
- #include "DragDrpB.cpp" // Platform-independent methods, if any
-
-
- SOM_Scope ODBoolean SOMLINK ODDragAndDropShowPasteAsDialog(ODDragAndDrop *somSelf, Environment *ev,
- ODBoolean canPasteLink,
- ODPasteAsMergeSetting mergeSetting,
- ODFacet* facet,
- ODTypeToken viewType,
- ODStorageUnit* contentSU,
- ODPasteAsResult* result)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropShowPasteAsDialog");
-
- SOM_TRY
-
- THROW_IF_NULL(facet, kODErrNullFacetInput);
- THROW_IF_NULL(contentSU, kODErrIllegalNullStorageUnitInput);
- THROW_IF_NULL(result, kODErrNullPasteAsResultInput);
-
- ODBoolean returnValue = ShowPasteAsDialog(
- canPasteLink,
- mergeSetting,
- (somSelf->GetDropResult(ev) == kODDropMove),
- contentSU,
- facet,
- viewType,
- result);
-
- return returnValue;
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- return kODFalse;
- }
-
- SOM_Scope void SOMLINK ODDragAndDropInitDragAndDrop(ODDragAndDrop *somSelf, Environment *ev,
- ODSession* session)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropInitDragAndDrop");
-
- SOM_TRY
-
- _fSession = session;
-
- somSelf->InitObject(ev);
-
- long gestaltResult;
- OSErr result;
-
- // Get the current process for background drag
- _fPSN = (ProcessSerialNumber*) ODNewPtr(sizeof(ProcessSerialNumber));
- GetCurrentProcess(_fPSN);
-
- _fReplaceFileEvent = (AppleEvent*) ODNewPtr(sizeof(AppleEvent));
- CreateReplaceFileEvent(ev,
- _fReplaceFileEvent,
- session,
- _fPSN);
-
- _fFacetsRejected = new OpenHashTable(OpenHashTable::StdEqual, OpenHashTable::StdHash, kODNULL);
- _fFacetsRejected->Initialize(kODInitialNumEntries,
- sizeof(ODFacet*),
- sizeof(ODFacet*));
-
- // Check if the drag manager is present
- result = Gestalt(gestaltDragMgrAttr, &gestaltResult);
- if (result != noErr)
- THROW_M(result, "Error from Gestalt");
-
- // The mysterious 31 is the bit position as BitTst uses a convention opposite to MC68000
- if (BitTst(&gestaltResult, (31 - gestaltDragMgrPresent)) == false) {
- THROW_M(kODErrNoDragManager, "No drag manager present");
- }
- else {
- // Install the default tracking handler for this application (session)
- _fTrackingHandler = NewDragTrackingHandlerProc(&MyDragTrackingHandler);
- result = InstallTrackingHandler(_fTrackingHandler, NULL, (void *) somSelf);
- ASSERTM(result == noErr, result, "Error from InstallTrackingHandler");
-
- // Install the default receive handler for this application (session)
- _fReceiveHandler = NewDragReceiveHandlerProc(&MyReceiveDropHandler);
- result = InstallReceiveHandler(_fReceiveHandler, NULL, (void *) somSelf);
- ASSERTM(result == noErr, result, "Error from InstallReceiveHandler");
-
- // Create a UPP for MySendDataProc which we will use later inside ::StartDrag
- _fSendDataHandler = NewDragSendDataProc(MySendDataProc);
-
- _fWindowState = _fSession->GetWindowState(ev);
-
- _fStorageSystem = _fSession->GetStorageSystem(ev);
-
- _fDragItemList = new LinkedList;
-
- AEEventHandlerUPP theHandlerUPP = NewAEEventHandlerProc( ReplaceFileAEHandler ) ;
- THROW_IF_ERROR(AEInstallEventHandler(kODShellSignature,
- kODReplaceFileEventID, theHandlerUPP, nil, false));
- }
-
- SOM_CATCH_ALL
-
- _fWindowState = kODNULL;
- _fStorageSystem = kODNULL;
- if (_fDragItemList)
- {
- delete _fDragItemList;
- _fDragItemList = kODNULL;
- }
- if (_fReceiveHandler)
- {
- RemoveReceiveHandler(_fReceiveHandler, NULL);
- DisposeRoutineDescriptor(_fReceiveHandler);
- _fReceiveHandler = kODNULL;
- }
- if (_fTrackingHandler)
- {
- RemoveTrackingHandler(_fTrackingHandler, NULL);
- DisposeRoutineDescriptor(_fTrackingHandler);
- _fTrackingHandler = kODNULL;
- }
- if (_fSendDataHandler)
- {
- DisposeRoutineDescriptor(_fSendDataHandler);
- _fSendDataHandler = kODNULL;
- }
-
- SOM_ENDTRY
- }
-
- SOM_Scope ODULong SOMLINK ODDragAndDropGetDragAttributes(ODDragAndDrop *somSelf, Environment *ev)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropGetDragAttributes");
-
- if (_fTrackingHandler == kODNULL)
- ODSetSOMException(ev, kODErrNoDragManager);
-
- return _fAttributes;
- }
-
- SOM_Scope ODPlatformDragReference SOMLINK ODDragAndDropGetDragReference(ODDragAndDrop *somSelf, Environment *ev)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropGetDragReference");
-
- if (_fTrackingHandler == kODNULL)
- ODSetSOMException(ev, kODErrNoDragManager);
-
- return _fDragReference;
- }
-
-
- SOM_Scope ODFacet* SOMLINK ODDragAndDropFindTargetFacet(ODDragAndDrop *somSelf, Environment *ev,
- ODPlatformWindow theWindow,
- ODPoint* mouse,
- ODPoint* localMouse)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropFindTargetFacet");
-
- ODFacet *targetFacet = kODNULL;
-
- if (_fTrackingHandler == kODNULL)
- ODSetSOMException(ev, kODErrNoDragManager);
- else {
- SOM_TRY
- ODFacet *curFacet;
- GrafPtr curPort;
- Point qdLocal;
-
- { TempODWindow targetWindow = _fWindowState->AcquireODWindow(ev,theWindow);
- if (!targetWindow)
- return kODNULL;
-
- GetPort(&curPort);
- SetPort(theWindow);
- qdLocal = mouse->AsQDPoint();
- GlobalToLocal(&qdLocal);
- *localMouse = qdLocal;
-
- SetPort(curPort);
-
- curFacet = targetWindow->GetFacetUnderPointForDrag(ev,
- localMouse);
- }
-
- while (curFacet && !targetFacet)
- {
- ODFrame* curFrame = curFacet->GetFrame(ev);
- #if ODDebug
- ODBoolean sample = kODFalse;
- sample = curFrame->IsDragging(ev);
- sample = curFrame->IsDroppable(ev);
- sample = curFrame->IsFrozen(ev);
- sample = IsNestedSelfEmbedding( somSelf, ev, curFrame );
- sample = _fFacetsRejected->Exists(&curFacet);
- #endif
- if (!curFrame->IsDragging(ev) &&
- curFrame->IsDroppable(ev) &&
- !curFrame->IsFrozen(ev) &&
- !IsNestedSelfEmbedding( somSelf, ev, curFrame ) &&
- !_fFacetsRejected->Exists(&curFacet))
- {
- targetFacet = curFacet;
- }
- curFacet = curFacet->GetContainingFacet(ev);
- }
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- }
- return targetFacet;
- }
-
- ODBoolean IsNestedSelfEmbedding( ODDragAndDrop *somSelf, Environment *ev, ODFrame* destFrame )
- {
- // Source frame: Frame that initiated the drag.
- // Destination frame: The frame where the drop will go.
- // Indirect parent frame: A frame which is the parent of one of the parent's of an embedded
- // frame. It can be anywhere in the hierarchy of embedded frames above the embedded frame
- // in question.
- // Direct Embedded frame: An embedded frame whose containing frame is the source frame.
- // Nested embedded frame: An embedded frame whose indirect parent frame is embedded in the source frame.
-
- // Want to check whether a drop destination is going to be in a nested embedded frame.
- // This will produce an infinite recursive situation when cloning.
-
- // Note: We only need to check for nested self embedding, since single self embedding is already
- // covered by the IsDragging flag.
-
- // Algorithm to check for self-embedding.
- // 1. Check if the destination frame's containing frame's IsDragging bit is set.
- // A. If so return true. This is nested self-embedding.
- // 2. Set the current frame to the containing frame of the destination frame.
- // 3. If not, continue this iteration:
- // A. Get the parent of the current frame and make it the current frame.
- // B. If the current frame's IsDragging bit is set, return true.
- // C. If the the current frame is null, return false.
- // D. If the the current frame == the source frame, return false. This means the frame was moved in the parent frame.
-
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODBoolean loopDone = kODFalse;
- ODBoolean selfEmbedding = kODFalse;
- ODFrame* frameToBeReleased = kODNULL;
-
- ODFrame* sourceFrame = somThis->fSourceFrame;
-
- TRY
- ODFrame* curFrame = destFrame->AcquireContainingFrame(ev);
-
- if( curFrame == kODNULL )
- {
- selfEmbedding = kODFalse;
- loopDone = kODTrue;
- }
- else if( curFrame == sourceFrame )
- {
- selfEmbedding = kODFalse;
- loopDone = kODTrue;
- }
- else if( curFrame->IsDragging(ev) == kODTrue)
- {
- selfEmbedding = kODTrue;
- loopDone = kODTrue;
- }
- frameToBeReleased = curFrame;
-
- while( !loopDone )
- {
- curFrame = curFrame->AcquireContainingFrame(ev);
- ODSafeReleaseObject( frameToBeReleased );
- frameToBeReleased = curFrame;
- if( curFrame == kODNULL )
- {
- selfEmbedding = kODFalse;
- loopDone = kODTrue;
- }
- else if( curFrame == sourceFrame )
- {
- selfEmbedding = kODFalse;
- loopDone = kODTrue;
- }
- else if( curFrame->IsDragging(ev) == kODTrue)
- {
- selfEmbedding = kODTrue;
- loopDone = kODTrue;
- }
- }
- CATCH_ALL
- ENDTRY
- ODSafeReleaseObject( frameToBeReleased );
-
- return selfEmbedding;
- }
-
- SOM_Scope void SOMLINK ODDragAndDropGetPromiseFromDragManager(ODDragAndDrop *somSelf, Environment *ev,
- ODPart* sourcePart,
- ODStorageUnitView* destSUView)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropGetPromiseFromDragManager");
-
- SOM_TRY
-
- if (_fTrackingHandler == kODNULL)
- THROW(kODErrNoDragManager);
-
- OSErr err;
-
- if (sourcePart != kODNULL) {
-
- ItemReference dragItemRef;
- err = GetDragItemReferenceNumber(_fDragReference, 1, &dragItemRef);
- ASSERTM(err == noErr, err, "Cannot get drag item reference in GetPromiseFromDragManager");
-
- ODPromiseDesc theInfo;
- theInfo.sourcePart = sourcePart;
- theInfo.destSUView = destSUView;
-
- // Set the offset of the suview to the beginning of the value
- destSUView->SetOffset(ev, 0);
-
- AEDesc dropLocation;
- err = AECreateDesc(kODPromiseDesc, (Ptr) &theInfo, sizeof(theInfo), &dropLocation);
- ASSERTM(err == noErr, err, "Error from AECreateDesc in GetPromiseFromDragManager");
-
- err = SetDropLocation(_fDragReference, &dropLocation);
- ASSERTM(err == noErr, err, "Error from SetDropLocation in GetPromiseFromDragManager");
-
- gIsResolvingPromise = kODTrue;
-
- long resolveResult;
- Size resolveSize = sizeof(long);
-
- err = GetFlavorData(_fDragReference, dragItemRef, kODPromiseFlavor, &resolveResult, &resolveSize, 0);
- ASSERTM(err == cantGetFlavorErr, err, "Cannot GetFlavorData in GetPromiseFromDragManager");
-
- AEDisposeDesc(&dropLocation);
-
- // Reset the Drop location.
-
- gIsResolvingPromise = kODFalse;
-
- theInfo.sourcePart = kODNULL;
- theInfo.destSUView = kODNULL;
-
- err = AECreateDesc(kODPromiseDesc, (Ptr) &theInfo, 0, &dropLocation);
- ASSERTM(err == noErr, err, "Error from AECreateDesc in GetPromiseFromDragManager");
-
- err = SetDropLocation(_fDragReference, &dropLocation);
- ASSERTM(err == noErr, err, "Error from SetDropLocation in GetPromiseFromDragManager");
-
- AEDisposeDesc(&dropLocation);
- }
- else {
- ODHandle dataHandle = kODNULL;
- ODType isoType = kODNULL;
- TRY
-
- ODTranslation* translate = _fSession->GetTranslation(ev);
- isoType = destSUView->GetType(ev);
- if (ODISOStrNCompare((ODISOStr) isoType,(ODISOStr) kODAppleFileTypePrefix, ODISOStrLength(kODAppleFileTypePrefix)) != 0) {
- ItemReference theItem;
- OSErr result;
- destSUView->SetOffset(ev,0);
- StorageUnitViewGetValue(destSUView, ev, sizeof(ItemReference), &theItem);
- ODPlatformType platformType = translate->GetPlatformTypeFromISOType(ev, isoType);
- if ( platformType == kODScrapTypestxt && !DragItemHasFlavor(_fDragReference, theItem, kODScrapTypestxt) )
- {
- // Create styled text from 'styl' and 'TEXT' flavors
- #ifdef ODDebug_DragAndDrop
- somPrintf("GetPromiseFromDragManager: Creating 'stxt' from 'styl' and 'TEXT'\n");
- #endif
- destSUView->SetOffset(ev,0);
- result = CopyFromDragItemInChunks(ev, kODScrapTypestyl, theItem, _fDragReference, destSUView);
- destSUView->SetOffset(ev, destSUView->GetSize(ev));
- result = CopyFromDragItemInChunks(ev, kODScrapTypeTEXT, theItem, _fDragReference, destSUView);
- }
- else
- {
- destSUView->SetOffset(ev,0);
- result = CopyFromDragItemInChunks(ev, platformType, theItem, _fDragReference, destSUView);
- }
- }
- ODDisposePtr(isoType);
-
- CATCH_ALL
-
- if (dataHandle)
- ODDisposeHandle(dataHandle);
- if (isoType)
- ODDisposePtr(isoType);
- RERAISE;
-
- ENDTRY
- }
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- }
-
- SOM_Scope void SOMLINK ODDragAndDropGetDataFromDragManager(ODDragAndDrop *somSelf, Environment *ev,
- ODStorageUnitView* suView)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropGetDataFromDragManager");
-
- WARN("ODDragAndDropGetDataFromDragManager is obsoleted.\n");
- }
-
- SOM_Scope void SOMLINK ODDragAndDropsomUninit(ODDragAndDrop *somSelf)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropsomUninit");
-
- Environment* ev = somGetGlobalEnvironment();
- somSelf->Clear(ev);
-
- if (_fDragItemList)
- {
- // _fDragItemList->DeleteAllLinks();
- delete _fDragItemList;
- }
- // if (_fDragItemIterator)
- // delete _fDragItemIterator;
- if (_fReceiveHandler)
- {
- RemoveReceiveHandler(_fReceiveHandler, NULL);
- DisposeRoutineDescriptor(_fReceiveHandler);
- }
- if (_fTrackingHandler)
- {
- RemoveTrackingHandler(_fTrackingHandler, NULL);
- DisposeRoutineDescriptor(_fTrackingHandler);
- }
- if (_fSendDataHandler)
- {
- DisposeRoutineDescriptor(_fSendDataHandler);
- }
-
- ODDeleteObject(_fFacetsRejected);
-
- ODDisposePtr(_fPSN);
- ODDisposePtr(_fReplaceFileEvent);
- }
-
- SOM_Scope void SOMLINK ODDragAndDropClear(ODDragAndDrop *somSelf, Environment *ev)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropClear");
-
- #if ODDebug_DragAndDrop
- somPrintf("In Clear\n");
- #endif
-
- SOM_TRY
- if (_fTrackingHandler == kODNULL)
- ODSetSOMException(ev, kODErrNoDragManager);
- else
- {
- if (_fDragItemIterator)
- {
- delete _fDragItemIterator;
- _fDragItemIterator = kODNULL;
- }
- _fDragItemList->DeleteAllLinks();
- }
-
- int refCnt = 0;
- if( _fMemItemContainer != kODNULL )
- {
- // Release temp in-memory container holding SU's for non-Bento files dragged in:
- ODByteArray ba = _fMemItemContainer->GetID(ev); // Get storage handle from container ID.
- WASSERT(ba._length==sizeof(ODHandle));
-
- if( _fCachedMemContainerDraft != kODNULL )
- {
- ODSafeReleaseObject( _fCachedMemContainerDraft ); // Undoes Acquire in EnterHandler.
- _fCachedMemContainerDraft = kODNULL;
- }
-
- ODDocument* doc = _fMemItemContainer->AcquireDocument(ev, kODDefaultDocument);
- if( doc != kODNULL )
- {
- WASSERT(( refCnt = doc->GetRefCount(ev) )==2);
- ODSafeReleaseObject( doc ); // Undoes our Acquire.
- ODSafeReleaseObject( doc ); // Undoes Acquire in EnterHandler.
- }
- WASSERT( (refCnt = _fMemItemContainer->GetRefCount(ev) )==1);
- ODSafeReleaseObject(_fMemItemContainer);
- _fMemItemContainer = kODNULL;
-
- ODDisposeHandle( *(ODHandle*)ba._buffer); // Finally dispose storage handle.
- delete ba._buffer;
-
- }
- SOM_CATCH_ALL
- // The clear method is a notification that parts are required to call as part of the drag and drop
- // protocal. Parts are not concerned with what this method does, or even if it succeeds. Calling this
- // method is its sole responsibility for the protocal, and does not have to respond to any problems.
- // Therefor, don't propogate any exceptions to the part.
- ODSetSOMException(ev, kODNoError);
- SOM_ENDTRY
-
- }
-
- SOM_Scope ODStorageUnit* SOMLINK ODDragAndDropGetContentStorageUnit(ODDragAndDrop *somSelf, Environment *ev)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropGetContentStorageUnit");
-
- ODStorageUnit* contentSU = kODNULL;
-
- if (_fTrackingHandler == kODNULL)
- ODSetSOMException(ev, kODErrNoDragManager);
- else {
- SOM_TRY
-
- ODMemDragItem *newItem;
- ODDragLink *newLink;
-
- if( _fMemItemContainer == kODNULL ) {
- ODHandle memContainerHandle = ODNewHandle(0);
- _fMemItemContainer = CreateMemoryContainer(ev, _fSession,
- memContainerHandle, kODBentoMemoryContainer);
- // _fMemItemContainer->Acquire(ev);
- ODDocument* theDocument = _fMemItemContainer->AcquireDocument( ev, kODDefaultDocument );
- _fCachedMemContainerDraft = theDocument->AcquireBaseDraft(ev, kODDPExclusiveWrite);
- // Refs to container/doc/draft will be released in Clear method.
- }
- newItem = new(ODGetDefaultHeap()) ODMemDragItem(_fStorageSystem, _fCachedMemContainerDraft, kODFalse, 0, 0, kODNULL);
- ASSERTM(newItem != kODNULL, kODErrCannotAllocateDragItem, "Error allocating drag item");
- newItem->Initialize(ev);
- newLink = new ODDragLink(newItem, kODTrue);
- if (!newLink)
- {
- delete newItem;
- ASSERTM(newLink != kODNULL, kODErrCannotAllocateDragItem, "Error allocating drag link");
- }
- _fDragItemList->AddLast(newLink);
- contentSU = newItem->GetStorageUnit(ev);
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- }
- return contentSU;
- }
-
- SOM_Scope ODDropResult SOMLINK ODDragAndDropStartDrag(ODDragAndDrop *somSelf, Environment *ev,
- ODFrame* srcFrame,
- ODType imageType,
- ODByteArray* image,
- ODPart** destPart,
- ODByteArray* refCon)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropStartDrag");
-
- LinkedListIterator *theIter = kODNULL; ODVolatile(theIter);
-
- SOM_TRY
- if (_fTrackingHandler == kODNULL)
- THROW(kODErrNoDragManager);
-
- ASSERT(image != kODNULL, kODErrIllegalNullInput);
- ASSERT(refCon != kODNULL, kODErrIllegalNullInput);
-
- OSErr result;
- RgnHandle imageRgn;
- ODTranslation *translate;
- ODULong count, index;
- ODType theISOType;
- ODPlatformType platformType;
- PromiseHFSFlavor thePromise;
- ODStorageUnit *theSU;
- ODDragLink *theDragLink;
-
- // Check if we know what the image type is
- ASSERTM(ODISOStrEqual(imageType, kODDragImageRegionHandle), kODErrUnknownDragImageType, "Unknown image type in StartDrag");
-
- // Set the drop result to kODDropFail. - VL
- _fDropResult = kODDropFail;
-
- // Begin the drag by creating a new drag reference
- result = NewDrag(&_fDragReference);
- ASSERTM(result == noErr, result, "Bad result from NewDrag");
-
- #ifdef ODDebug_DragAndDrop
- // PrintDragReference(_fDragReference, "After NewDrag");
- #endif
-
- // Register a send procedure so we don't have to cache any data with the drag manager
- result = SetDragSendProc(_fDragReference, _fSendDataHandler, (void *) somSelf);
- ASSERTM(result == noErr, result, "Bad result from SetDragSendProc");
-
- // Scan through all items in the drag and add a flavor for each value
- // in the storage unit's kODContents property
- theIter = new LinkedListIterator(_fDragItemList);
- translate = _fSession->GetTranslation(ev);
- imageRgn = *((RgnHandle*) image->_buffer);
- for (theDragLink = (ODDragLink*)theIter->First(); theDragLink; theDragLink = (ODDragLink*)theIter->Next())
- {
- theSU = theDragLink->fItem->GetStorageUnit(ev);
- ODBoolean userPromise = ODSUExistsThenFocus(ev, theSU, kODPropContents, kODHFSPromise);
- if (userPromise)
- {
- ODByteArray ba;
- ODPart* dummySourcePart;
- theSU->GetPromiseValue(ev, kODHFSPromise, 0, sizeof(PromiseHFSFlavor), &ba, &dummySourcePart);
- if (ba._buffer)
- {
- ODBlockMove(ba._buffer, &thePromise, ba._length);
- ODDisposePtr(ba._buffer);
- }
- thePromise.promisedFlavor = kODUserPromiseFlavor;
- }
- else
- {
- // Always promise a file in case somebody wishes to drag this out to the finder
- thePromise.fileType = GetStorageUnitOSType(ev,theSU);
- thePromise.fileCreator = ODGetIconFilePlatformCreatorFromPartSU(ev,theSU);
- thePromise.fdFlags = 0;
- thePromise.promisedFlavor = kODBentoFlavor;
- }
- result = AddDragItemFlavor(_fDragReference, (ItemReference)(theDragLink->fItem), flavorTypePromiseHFS,
- &thePromise, sizeof(PromiseHFSFlavor), 0);
- ASSERTM(result == noErr, result, "Bad result from AddDragItemFlavor");
-
- result = AddDragItemFlavor(_fDragReference, (ItemReference)(theDragLink->fItem), (userPromise ? kODUserPromiseFlavor : kODBentoFlavor), 0L, 0L, 0);
- ASSERTM(result == noErr, result, "Bad result from AddDragItemFlavor");
-
- result = SetDragItemBounds(_fDragReference, (ItemReference)(theDragLink->fItem), &((**imageRgn).rgnBBox));
- ASSERTM(result == noErr, result, "Bad result from SetDragItemBounds");
-
- #ifdef ODDebug_DragAndDrop
- // PrintStorageUnit(ev, theSU, "DragItem SU");
- #endif
- theSU->Focus(ev,kODPropContents, kODPosUndefined, 0, 0, kODPosUndefined);
- count = theSU->CountValues(ev);
- for (index = 1; index <= count; ++index)
- {
- theSU->Focus(ev,kODPropContents, kODPosUndefined, 0, index, kODPosUndefined);
- theISOType = theSU->GetType(ev);
- platformType = translate->GetPlatformTypeFromISOType(ev, theISOType);
- ODDisposePtr(theISOType);
- if (!platformType)
- continue;
- result = AddDragItemFlavor(_fDragReference, (ItemReference)(theDragLink->fItem), platformType, 0L, 0L, 0);
- ASSERTM(result == noErr, result, "Bad result from AddDragItemFlavor");
-
- // If styled text ('stxt') was just added, also add 'styl' if
- // a 'TEXT' representation will also be written.
- if ( (platformType == kODScrapTypestxt)
- && theSU->Exists(ev, kODPropContents, kODAppleTEXT, 0)
- && !theSU->Exists(ev, kODPropContents, kODApplestyl, 0) )
- {
- result = AddDragItemFlavor(_fDragReference, (ItemReference)(theDragLink->fItem), kODScrapTypestyl, 0L, 0L, 0);
- ASSERTM(result == noErr, result, "Bad result from AddDragItemFlavor");
- }
- }
-
- // Always add our special dummy promise to the drag
- result = AddDragItemFlavor(_fDragReference, (ItemReference)(theDragLink->fItem), kODPromiseFlavor, 0L, 0L, 0);
- ASSERTM(result == noErr, result, "Bad result from adding kODPromiseFlavor");
- }
-
- _fSourceFrame = srcFrame;
- _fSourcePart = srcFrame->AcquirePart(ev);
-
- TRY
- TempDelayBentoFatalError tempDelay; // delay in drag&drop
-
- _fDestFacet = kODNULL;
- _fDragItemIterator = new ODDragItemIterator();
- THROW_IF_NULL(_fDragItemIterator, kODErrOutOfMemory);
- _fDragItemIterator->InitDragItemIterator(ev, theIter);
- _fHasLeftSourceFrame = kODFalse;
- _fHasLeftSourcePart = kODFalse;
-
- #ifdef ODDebug_DragAndDrop
- // PrintDragReference(_fDragReference, "Before TrackDrag");
- #endif
-
- // Do the drag
- result = TrackDrag(_fDragReference, *((EventRecord**) refCon->_buffer), imageRgn);
-
- if( result != noErr )
- THROW( result );
- if (_fDestFacet)
- *destPart = _fDestFacet->GetFrame(ev)->AcquirePart(ev);
- else
- *destPart = kODNULL;
- CATCH_ALL
- DisposeDrag(_fDragReference);
- _fDragReference = kODNULL;
- ODSafeReleaseObject( _fSourcePart);
- _fSourcePart = kODNULL;
- RERAISE;
- ENDTRY
-
- DisposeDrag(_fDragReference);
- _fDragReference = kODNULL;
- // if( _fDragItemIterator != kODNULL )
- // {
- // delete _fDragItemIterator;
- // _fDragItemIterator = kODNULL;
- // }
-
- _fSourceFrame = kODNULL;
- ODSafeReleaseObject( _fSourcePart );
- _fSourcePart = kODNULL;
- _fDestFacet = kODNULL;
- somSelf->Clear(ev);
-
- if (_fShouldSendReplaceFileEvent)
- {
- _fShouldSendReplaceFileEvent = kODFalse;
- OSErr err = SetupReplaceFileEvent(ev,
- _fReplaceFileEvent,
- &gTmpFileFSSpec,
- &gTargetFSSpec);
- SendReplaceFileEvent(_fReplaceFileEvent, _fPSN);
- DisposeReplaceFileEvent(_fReplaceFileEvent);
- CreateReplaceFileEvent(ev,
- _fReplaceFileEvent,
- _fSession,
- _fPSN);
- }
-
- SOM_CATCH_ALL
-
- if( _fDragItemIterator != kODNULL )
- {
- delete _fDragItemIterator;
- _fDragItemIterator = kODNULL;
- }
- somSelf->Clear(ev);
- if (_fDragReference)
- DisposeDrag(_fDragReference);
- _fDragReference = kODNULL;
-
- SOM_ENDTRY
-
- if (_fDropResult == kODDropMove)
- return kODDropMove;
- else if (_fDropResult == kODDropCopy)
- return kODDropCopy;
- else
- return kODDropFail;
- }
-
-
- SOM_Scope LinkedList* SOMLINK ODDragAndDropGetDragItemList(ODDragAndDrop *somSelf, Environment *ev)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropGetDragItemList");
-
- return _fDragItemList;
- }
-
- SOM_Scope void SOMLINK ODDragAndDropSetDragItemList(ODDragAndDrop *somSelf, Environment *ev,
- LinkedList* list)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropSetDragItemList");
-
- _fDragItemList = list;
- }
-
- SOM_Scope ODBoolean SOMLINK ODDragAndDropGetListFromHandler(ODDragAndDrop *somSelf, Environment *ev)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropGetListFromHandler");
-
- return _fListFromHandler;
- }
-
- SOM_Scope void SOMLINK ODDragAndDropSetListFromHandler(ODDragAndDrop *somSelf, Environment *ev,
- ODBoolean listFromHandler)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropSetListFromHandler");
-
- _fListFromHandler = listFromHandler;
- }
-
- SOM_Scope ODFrame* SOMLINK ODDragAndDropGetSourceFrame(ODDragAndDrop *somSelf, Environment *ev)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropGetSourceFrame");
-
- return _fSourceFrame;
- }
-
- SOM_Scope void SOMLINK ODDragAndDropSetSourceFrame(ODDragAndDrop *somSelf, Environment *ev,
- ODFrame* sourceFrame)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropSetSourceFrame");
-
- _fSourceFrame = sourceFrame;
- }
-
- SOM_Scope ODULong SOMLINK ODDragAndDropGetAttributes(ODDragAndDrop *somSelf, Environment *ev)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropGetAttributes");
-
- return _fAttributes;
- }
-
- SOM_Scope void SOMLINK ODDragAndDropSetAttributes(ODDragAndDrop *somSelf, Environment *ev,
- ODULong attr)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropSetAttributes");
-
- _fAttributes = attr;
- }
-
- SOM_Scope ODPart* SOMLINK ODDragAndDropGetSourcePart(ODDragAndDrop *somSelf, Environment *ev)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropGetSourcePart");
-
- return _fSourcePart;
- }
-
- SOM_Scope void SOMLINK ODDragAndDropSetSourcePart(ODDragAndDrop *somSelf, Environment *ev,
- ODPart* sourcePart)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropSetSourcePart");
-
- _fSourcePart = sourcePart;
- }
-
- SOM_Scope ODDragItemIterator* SOMLINK ODDragAndDropGetDragItemIterator(ODDragAndDrop *somSelf, Environment *ev)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropGetDragItemIterator");
-
- return _fDragItemIterator;
- }
-
- SOM_Scope void SOMLINK ODDragAndDropSetDragItemIterator(ODDragAndDrop *somSelf, Environment *ev,
- ODDragItemIterator* iter)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropSetDragItemIterator");
-
- _fDragItemIterator = iter;
- }
-
- SOM_Scope ODSession* SOMLINK ODDragAndDropGetSession(ODDragAndDrop *somSelf, Environment *ev)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropGetSession");
-
- return _fSession;
- }
-
- SOM_Scope ODStorageSystem* SOMLINK ODDragAndDropGetStorageSystem(ODDragAndDrop *somSelf, Environment *ev)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropGetStorageSystem");
-
- return _fStorageSystem;
- }
-
- SOM_Scope void SOMLINK ODDragAndDropSetDragReference(ODDragAndDrop *somSelf, Environment *ev,
- ODPlatformDragReference dragReference)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropSetDragReference");
-
- _fDragReference = dragReference;
- }
-
- SOM_Scope ODFacet* SOMLINK ODDragAndDropGetPrevFacet(ODDragAndDrop *somSelf, Environment *ev)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropGetPrevFacet");
-
- return _fPrevFacet;
- }
-
- SOM_Scope void SOMLINK ODDragAndDropSetPrevFacet(ODDragAndDrop *somSelf, Environment *ev,
- ODFacet* prevFacet)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropSetPrevFacet");
-
- _fPrevFacet = prevFacet;
- }
-
- SOM_Scope ODFacet* SOMLINK ODDragAndDropGetDestFacet(ODDragAndDrop *somSelf, Environment *ev)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropGetDestFacet");
-
- return _fDestFacet;
- }
-
- SOM_Scope void SOMLINK ODDragAndDropSetDestFacet(ODDragAndDrop *somSelf, Environment *ev,
- ODFacet* destFacet)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropSetDestFacet");
-
- _fDestFacet = destFacet;
- }
-
- SOM_Scope ODDropResult SOMLINK ODDragAndDropGetDropResult(ODDragAndDrop *somSelf, Environment *ev)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropGetDropResult");
-
- return _fDropResult;
- }
-
- SOM_Scope void SOMLINK ODDragAndDropSetDropResult(ODDragAndDrop *somSelf, Environment *ev,
- ODDropResult dropResult)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropSetDropResult");
-
- _fDropResult = dropResult;
- }
-
- SOM_Scope ProcessSerialNumber* SOMLINK ODDragAndDropGetPSN(ODDragAndDrop *somSelf, Environment *ev)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropGetDropResult");
-
- return _fPSN;
- }
-
- SOM_Scope AppleEvent* SOMLINK ODDragAndDropGetReplaceFileEvent(ODDragAndDrop *somSelf, Environment *ev)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropGetDropResult");
-
- return _fReplaceFileEvent;
- }
-
- SOM_Scope void SOMLINK ODDragAndDropSetShouldSendReplaceFileEvent(ODDragAndDrop *somSelf, Environment *ev,
- ODBoolean shouldSend)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropGetDropResult");
-
- _fShouldSendReplaceFileEvent = shouldSend;
- }
-
- pascal OSErr MyDragTrackingHandler(
- short message,
- WindowPtr theWindow,
- void* handlerRefCon,
- ODPlatformDragReference theDrag)
- {
- ODDragAndDrop *self = (ODDragAndDrop*)handlerRefCon;
- ODPoint mouse, localMouse;
- OSErr returnCode = noErr;
-
- TRY
- TempDelayBentoFatalError tempDelay; // delay in drag&drop
-
- Environment* ev = somGetGlobalEnvironment();
-
- switch (message)
- {
- case dragTrackingEnterHandler:
- returnCode = self->EnterHandler(ev, theDrag);
- break;
- case dragTrackingEnterWindow:
- returnCode = self->EnterWindow(ev, theDrag, theWindow);
- break;
-
- case dragTrackingInWindow:
- returnCode = self->InWindow(ev, theDrag, theWindow);
- break;
-
- case dragTrackingLeaveWindow:
- returnCode = self->LeaveWindow(ev, theDrag, theWindow);
- break;
-
- case dragTrackingLeaveHandler:
- returnCode = self->LeaveHandler(ev);
- break;
- }
-
- CATCH_ALL
-
- returnCode = ErrorCode();
-
- ENDTRY
-
- return returnCode;
- }
-
- pascal OSErr MyReceiveDropHandler(
- WindowPtr theWindow,
- void* handlerRefCon,
- ODPlatformDragReference theDrag)
- {
- ODDragAndDrop *self = (ODDragAndDrop*)handlerRefCon;
- ODPoint mouse, localMouse;
- Point qdMouse;
- ODFacet *targetFacet;
- OSErr returnCode = noErr;
-
- #ifdef ODDebug_DragAndDrop
- somPrintf("MyReceiveDropHandler\n");
- #endif
-
- Environment* ev = somGetGlobalEnvironment();
-
- TRY
- TempDelayBentoFatalError tempDelay; // delay in drag&drop
-
- GetDragMouse(theDrag, &qdMouse, 0L);
- mouse = qdMouse;
- targetFacet = self->FindTargetFacet(ev, theWindow, &mouse, &localMouse);
-
- if (!targetFacet || !(self->GetDragItemList(ev)->Count()))
- returnCode = dragNotAcceptedErr;
- else
- {
- TempODPart targetPart = targetFacet->GetFrame(ev)->AcquirePart(ev);
-
- // Assume _fDropResult is kODDropMove
-
- self->SetDropResult(ev, kODDropMove);
-
- // Are we going across Drafts?
-
- ODPart* sourcePart = self->GetSourcePart(ev);
- if ((sourcePart == kODNULL) ||
- (targetPart->GetStorageUnit(ev)->GetDraft(ev) !=
- sourcePart->GetStorageUnit(ev)->GetDraft(ev)))
- self->SetDropResult(ev, kODDropCopy);
-
- ODSShort mouseDownModifiers;
- ODSShort mouseUpModifiers;
-
- GetDragModifiers(self->GetDragReference(ev), 0L, &mouseDownModifiers, &mouseUpModifiers);
-
- // Check the mandatory modifier keys first
-
- if (mouseUpModifiers & optionKey) {
- self->SetDropResult(ev, kODDropCopy);
- SetPasteAsAttribute(self, ev, mouseUpModifiers);
- }
- else if (mouseUpModifiers & controlKey) {
- self->SetDropResult(ev, kODDropMove);
- SetPasteAsAttribute(self, ev, mouseUpModifiers);
- }
- else if (mouseUpModifiers & cmdKey) {
- SetPasteAsAttribute(self, ev, mouseUpModifiers);
- }
-
- // Then check the optional modifier keys
-
- else if (mouseDownModifiers & optionKey) {
- self->SetDropResult(ev, kODDropCopy);
- SetPasteAsAttribute(self, ev, mouseDownModifiers);
- }
- else if (mouseDownModifiers & controlKey) {
- self->SetDropResult(ev, kODDropMove);
- SetPasteAsAttribute(self, ev, mouseDownModifiers);
- }
- else if (mouseDownModifiers & cmdKey) {
- SetPasteAsAttribute(self, ev, mouseDownModifiers);
- }
-
- // Check to see whether it is an override by source part.
- ODDragItemIterator* dragItemIter = self->GetDragItemIterator(ev);
- if (dragItemIter)
- {
- ODStorageUnit* su = dragItemIter->First(ev);
- ODDraft* draft = su->GetDraft(ev);
- ODCloneKind cloneKind = GetOriginalCloneKind(ev, draft);
- if (cloneKind == kODCloneCopy)
- self->SetDropResult(ev, kODDropCopy);
- }
-
- // Drop
- #ifdef ODDebug_DragAndDrop
- somPrintf("Calling Drop on targetFacet %x\n", targetFacet);
- #endif
-
- self->SetAttributes(ev, self->GetAttributes(ev) |
- (self->GetDropResult(ev) == kODDropMove ? kODDropIsMove : kODDropIsCopy));
-
- if (targetFacet->GetFrame(ev) == self->GetSourceFrame(ev))
- self->SetAttributes(ev, self->GetAttributes(ev) | (kODDropIsInSourceFrame | kODDropIsInSourcePart));
- else if (targetPart == self->GetSourcePart(ev))
- self->SetAttributes(ev, self->GetAttributes(ev) | kODDropIsInSourcePart);
-
- self->SetDestFacet(ev, targetFacet);
- self->SetPrevFacet(ev, kODNULL);
- ODULong dropResult; ODVolatile(dropResult);
- SOM_TRY
- dropResult= targetFacet->Drop(ev, &localMouse, self->GetDragItemIterator(ev), kODNULL);
- SOM_CATCH_ALL
- SOM_ENDTRY
- if (dropResult == kODDropFail) {
- self->SetDropResult(ev, dropResult);
- returnCode = dragNotAcceptedErr;
- // returnCode = ErrorCode();
- }
- else if ((self->GetDropResult(ev) == kODDropMove) && (dropResult == kODDropCopy)) {
- self->SetDropResult(ev, kODDropCopy);
- returnCode = noErr;
- }
-
- ODDragItemIterator* iter = self->GetDragItemIterator(ev);
- ODSession* destSession = self->GetSession(ev);
- for (ODStorageUnit* su = iter->First(ev); iter->IsNotComplete(ev); su = iter->Next(ev)) {
- ODSession* sourceSession = su->GetSession(ev);
- if ((sourceSession != kODNULL) && (sourceSession != destSession)) {
- ODDragAndDrop* sourceDAD = sourceSession->GetDragAndDrop(ev);
- if (sourceDAD != kODNULL) {
- sourceDAD->SetDropResult(ev, self->GetDropResult(ev));
- sourceDAD->SetDestFacet(ev, targetFacet);
- }
- }
- }
- }
-
- CATCH_ALL
-
- self->SetDropResult(ev, kODDropFail);
- returnCode = dragNotAcceptedErr;
- #if ODDebug
- somPrintf("Error in MyReceiveDropHandler.\n");
- #endif
-
- ENDTRY
-
- ODEventData event;
- WaitNextEvent(mUpMask, (EventRecord*) &event, 0, kODNULL);
- #if ODDebug_DragAndDrop
- somPrintf("message %x when %x where %x modifier %x\n", event.message, event.when, event.where, event.modifiers);
- #endif
-
- return returnCode;
- }
-
- pascal OSErr MySendDataProc(
- FlavorType theType,
- void* refCon,
- ItemReference theItem,
- ODPlatformDragReference theDrag)
- {
- ODDragAndDrop *self = (ODDragAndDrop*)refCon;
- Environment* ev = somGetGlobalEnvironment();
- OSErr result = noErr;
- ODType theISOType;
- ODTranslation *translate;
- AEDesc dropDescriptor;
- ODPtr stylPtr = kODNULL;
- ODULong stylSize = 0;
-
- ODVolatile(result);
- TRY
-
- TempDelayBentoFatalError tempDelay; // delay in drag&drop
-
- LinkedListIterator iter(self->GetDragItemList(ev));
- ODDragLink* theDragLink = kODNULL;
- ODMemDragItem* theDragItem = kODNULL;
-
- #ifdef ODDebug_DragAndDrop
- somPrintf("Entering MySendDataProc.\n");
- #endif
-
- for (theDragLink = (ODDragLink*)iter.First();
- theDragLink; theDragLink = (ODDragLink*)iter.Next())
- {
- if (theDragLink->fItem == (ODDragItem*)theItem)
- {
- theDragItem = (ODMemDragItem*) theDragLink->fItem;
- break;
- }
- }
- if (!theDragItem)
- {
- WARN("Item not found in send proc");
- result = badDragFlavorErr;
- }
- else {
- switch (theType)
- {
- case kODPromiseFlavor:
- #ifdef ODDebug_DragAndDrop
- somPrintf("MySendDataProc: kODPromiseFlavor\n");
- #endif
- if (gIsResolvingPromise)
- {
- result = GetDropLocation(theDrag, &dropDescriptor);
- if ((result != noErr) || (dropDescriptor.descriptorType != kODPromiseDesc)) {
- WARN("Error from GetDropLocation in send procedure");
- }
- else {
- ODPromiseDesc theInfo;
- ODBlockMove((Ptr)(*dropDescriptor.dataHandle), (Ptr)&theInfo, sizeof(ODPromiseDesc));
- if (theInfo.sourcePart && theInfo.destSUView)
- {
- TRY
- theInfo.sourcePart->FulfillPromise(ev, theInfo.destSUView);
- CATCH_ALL
- WARN("Error from FulfillPromise.");
- ENDTRY
- }
- result = noErr;
- }
- }
- break;
- case kODUserPromiseFlavor:
- #ifdef ODDebug_DragAndDrop
- somPrintf("MySendDataProc: kODUserPromiseFlavor\n");
- #endif
- result = noErr;
- ODStorageUnit* contentSU = theDragItem->GetStorageUnit(ev);
- if ((contentSU != kODNULL) && (contentSU->Exists(ev, kODPropContents, kODHFSPromise, 0)))
- {
- FSSpec dropFSSpec;
- result = GetDropFSSpec(theDrag, dropFSSpec);
- if (result == noErr)
- {
- TRY
- contentSU->Focus(ev, kODPropContents, kODPosUndefined, kODHFSPromise, 0, kODPosUndefined);
- StorageUnitSetPromiseValue(contentSU, ev, kODHFSPromise, 0, sizeof(FSSpec), &dropFSSpec, self->GetSourcePart(ev));
- contentSU->Focus(ev, kODPropContents, kODPosUndefined, kODHFSPromise, 0, kODPosUndefined);
- ODULong size = StorageUnitGetValue(contentSU, ev, sizeof(FSSpec), &dropFSSpec);
- if (size != sizeof(FSSpec))
- {
- self->SetDropResult(ev, kODDropFail);
- result = fnfErr;
- }
- else
- {
- self->SetDropResult(ev, IsTrashFolder(dropFSSpec) ? kODDropMove : kODDropCopy);
- SetDragItemFlavorData(theDrag, theItem, theType, &dropFSSpec, sizeof(FSSpec), 0L);
- }
- CATCH_ALL
- WARN("Error from FulfillPromise.");
- ENDTRY
- }
- // If we get a file not found error, most likely we are trying to drag to somewhere other than the Finder.
- // That's OK, so just eat the error.
- if( result == fnfErr )
- result = noErr;
- }
- break;
- case kODBentoFlavor:
- {
- #ifdef ODDebug_DragAndDrop
- somPrintf("MySendDataProc: kODBentoFlavor\n");
- #endif
- // Check the drop location (probably from the finder)
- FSSpec dropFSSpec;
-
- result = GetDropFSSpec(theDrag, dropFSSpec);
- if (result == noErr)
- {
- ODSShort mouseDownModifiers;
- ODSShort mouseUpModifiers;
-
- GetDragModifiers(self->GetDragReference(ev), 0L, &mouseDownModifiers, &mouseUpModifiers);
-
- // Check the mandatory modifier keys first
-
- if (mouseUpModifiers & controlKey)
- self->SetDropResult(ev, kODDropMove); // Need to take care of moving to the Finder.
- else
- self->SetDropResult(ev, kODDropFail); // Copied to non OpenDoc process, so return fail so part will
- // not post undo action.
- boolean nameFromPart = MakeUniqueFilename(ev, self->GetSession(ev), theDragItem->GetStorageUnit(ev), &dropFSSpec);
-
- // Drags to the Trash are always a move
- boolean isDraggingToTrash = IsTrashFolder(dropFSSpec);
-
- if (isDraggingToTrash)
- {
- self->SetDropResult(ev, kODDropMove); // Dragged to Trash, so it's a move.
-
- TempPlatformFile file = new PlatformFile;
- file->Specify(&dropFSSpec);
-
- if (file->Exists())
- {
- // If the target file exists in trash already,
- // set the fsspec to the temp folder.
- RespecifyToTempFolder(file);
-
- // Clone the data.
- CloneIntoFile(ev, theDragItem, file->GetFileSpec());
-
- // After cloning the data to the file (in temp folder),
- // move to it trash.
- file->MoveToTrash();
-
- // Set the result for Drag Manager.
- SetDragItemFlavorData(theDrag, theItem, theType, &(file->GetFileSpec()), sizeof(FSSpec), 0L);
- }
- else
- {
- CloneIntoFlavor(ev, self, theDragItem,
- theDrag, theItem, theType,
- dropFSSpec);
- }
- }
- else if (!nameFromPart)
- {
- CloneIntoFlavor(ev, self, theDragItem,
- theDrag, theItem, theType,
- dropFSSpec);
- }
- else if (IsFrontProcess())
- {
- TempPlatformFile file = new PlatformFile;
- file->Specify(&dropFSSpec);
-
- if (file->Exists())
- {
- ParamText(dropFSSpec.name, "\p", "\p", "\p");
- if (ODAskUserReplace(ev, self->GetSession(ev)))
- {
- file->MoveToTrash();
- CloneIntoFlavor(ev, self, theDragItem,
- theDrag, theItem, theType,
- dropFSSpec);
- }
- }
- else
- {
- CloneIntoFlavor(ev, self, theDragItem,
- theDrag, theItem, theType,
- dropFSSpec);
- }
- }
- else
- {
- TempPlatformFile file = new PlatformFile;
- file->Specify(&dropFSSpec);
-
- if (file->Exists())
- {
- FSSpec targetFSSpec = file->GetFileSpec();
- RespecifyToTempFolder(file);
- FSSpec tmpFileFSSpec = file->GetFileSpec();
- CloneIntoFile(ev, theDragItem, tmpFileFSSpec);
- // Not notifying the target through SetDragItemData on purpose becuase we are going all the work.
-
- gTargetFSSpec = targetFSSpec;
- gTmpFileFSSpec = tmpFileFSSpec;
- self->SetShouldSendReplaceFileEvent(ev, kODTrue);
- }
- else
- {
- CloneIntoFlavor(ev, self, theDragItem,
- theDrag, theItem, theType,
- dropFSSpec);
- }
- }
- }
- // If we are not dragging to a file, create a Drag item for the Bento Container.
- // This allows other applications to support OpenDoc Bento types (like the Scrapbook,
- // or Container apps).
- else if ( result == fnfErr )
- {
- ODULong dropResult;
-
- // At this point, Doug says only a memory container is being
- // modified in any way, so we can suppress fatal errors:
- TempSuppressFatalBentoError tempSuppress;
-
- ODSShort mouseDownModifiers;
- ODSShort mouseUpModifiers;
-
- GetDragModifiers(self->GetDragReference(ev), 0L, &mouseDownModifiers, &mouseUpModifiers);
-
- // Check the mandatory modifier keys first. We want to allow moving to a non-OpenDoc process,
- // instead of just copies.
-
- if (mouseUpModifiers & controlKey)
- dropResult = kODDropMove;
- else
- dropResult = kODDropCopy;
-
- OSErr e =
- CopyMemContainerToDragItemInChunks( ev, self->GetSession(ev), theType, theItem, theDrag, theDragItem );
-
- dropResult = kODDropFail; // Dragged to non OpenDoc process, so return fail so part will
- // post undo action.
- self->SetDropResult(ev, dropResult);
- return e;
- }
- }
- break;
- default:
- #ifdef ODDebug_DragAndDrop
- somPrintf("MySendDataProc: Default\n");
- #endif
- self->SetDropResult(ev, kODDropFail);
- translate = self->GetSession(ev)->GetTranslation(ev);
- theISOType = translate->GetISOTypeFromPlatformType(ev, theType, kODPlatformDataType);
- if (ODSUExistsThenFocus(ev, theDragItem->GetStorageUnit(ev),kODPropContents, theISOType))
- {
- result = CopyToDragItemInChunks(ev, theType, theItem, theDrag, theDragItem);
- if (result == noErr)
- self->SetDropResult(ev, kODDropCopy);
- }
- else if ( (theType == kODScrapTypestyl) && StorageUnitGetStylFromStyledText(theDragItem->GetStorageUnit(ev), ev, &stylSize, &stylPtr) )
- {
- result = SetDragItemFlavorData(theDrag, theItem, theType, stylPtr, stylSize, 0L);
- WASSERTM(result == noErr, "Error from SetDragItemFlavorData in send procedure");
- if (result == noErr)
- self->SetDropResult(ev, kODDropCopy);
- ODDisposePtr(stylPtr);
- stylPtr = kODNULL;
- }
- else
- {
- WARN("Send procedure can not supply this type");
- result = badDragFlavorErr;
- }
- ODDisposePtr(theISOType);
- }
- }
-
- CATCH_ALL
-
- self->SetShouldSendReplaceFileEvent(ev, kODFalse);
- result = ErrorCode();
- WARN("MySendDataProc: %d", result);
-
- ENDTRY
-
- return result;
- }
-
- static OSErr CopyMemContainerToDragItemInChunks(Environment* ev,
- ODSession* theSession,
- FlavorType theType,
- ItemReference theItem,
- ODPlatformDragReference theDrag,
- ODDragItem* theDragItem)
- {
- const ODULong kCopyBlockSize = 512;
- OSErr result = noErr;
- ODPtr dataPtr;
- ODULong dataSize;
-
- TRY
- // Now write out the entire Container for the Memory Drag item.
- ODMemDragItem* tempDItem = (ODMemDragItem*)theDragItem;
-
- // Clone the D&D container to a temp draft, then return the data handle from the temp container.
- // We cannot directly get the data handle from the D&D container, because the full data isn't written
- // until we close the container, but we can't do that yet because there could be further promises
- // pending against it.
- TempODHandle theMemDragItemContainerData = CloneToTempMemContainer( ev, tempDItem, theSession );
-
- ODLockHandle( theMemDragItemContainerData );
-
- dataPtr = *theMemDragItemContainerData;
- dataSize = ODGetHandleSize( theMemDragItemContainerData );
- WASSERTM( dataSize != 0, "Zero size memory container handle.");
-
- ODULong currentByte = 0;
- while ((currentByte < dataSize) && (result == noErr)) {
- ODULong bytesRead;
- if( ( dataSize - currentByte ) >= kCopyBlockSize )
- bytesRead = kCopyBlockSize;
- else
- bytesRead = dataSize - currentByte;
-
- result = SetDragItemFlavorData(theDrag, theItem, theType, ODPtr((ODULong)dataPtr + currentByte), bytesRead, currentByte);
- WASSERTM(result == noErr, "Error from SetDragItemFlavorData in CopyToDragItemInChunks.");
- currentByte += bytesRead;
- }
- WASSERTM(currentByte == dataSize, "Bytes written is NOT equal to dataSize.");
- CATCH_ALL
- result = dragNotAcceptedErr;
- ENDTRY
- return result;
- }
-
- static ODHandle CloneToTempMemContainer( Environment* ev, ODMemDragItem* tempDItem, ODSession* theSession )
- {
- ODStorageUnit* contentSU = tempDItem->GetStorageUnit(ev);
- ODID targetContentFrameID = kODNULLID;
- ODHandle containerHandle = ODNewHandle(0);
- ODStorageUnitID suID;
- TRY
- TempODContainer tempContainer = CreateMemoryContainer(ev, theSession, containerHandle, kODBentoMemoryContainer);
- TempODDocument tempDocument = tempContainer->AcquireDocument(ev, kODDefaultDocument);
- TempODDraft targetDraft = tempDocument->AcquireBaseDraft(ev, kODDPExclusiveWrite);
- TempODStorageUnit targetSU = targetDraft->CreateStorageUnit(ev);
-
- { TempODStorageUnit draftProperties = targetDraft->AcquireDraftProperties(ev);
- ODSetStrongSURefProp(ev, draftProperties, kODPropRootPartSU, kODStrongStorageUnitRef,targetSU->GetID(ev));
- suID = ODGetStrongSURefProp(ev, draftProperties, kODPropRootPartSU, kODStrongStorageUnitRef);
- }
-
- ODDraft* sourceDraft = contentSU->GetDraft(ev);
- ODDraftKey cloneKey = 0;
- TRY
- cloneKey = sourceDraft->BeginClone(ev, targetDraft, kODNULL, kODCloneToFile);
- sourceDraft->Clone(ev, cloneKey, contentSU->GetID(ev), targetSU->GetID(ev), 0);
- ODID contentFrameID = ODGetWeakSURefProp(ev, contentSU, kODPropContentFrame, kODWeakStorageUnitRef);
- if (contentFrameID != kODNULLID)
- {
- targetContentFrameID = sourceDraft->Clone(ev, cloneKey, contentFrameID, kODNULLID, 0);
- }
- sourceDraft->EndClone(ev, cloneKey);
- CATCH_ALL
- sourceDraft->AbortClone(ev, cloneKey);
-
- ENDTRY
-
- ODSURemoveProperty(ev, targetSU, kODPropMouseDownOffset);
-
- // first externalize the container
- // Externalize may fail with an iterator-out-of-sync error because
- // resolving promises may add storage units to the draft's collection
- // during iteration. In theory, the only promises should be in the
- // root storage unit, so explicitly externalize it first to resolve
- // promises before interating over all storage units.
- if( targetSU )
- targetSU->Externalize(ev);
- targetDraft->Externalize(ev);
-
- CATCH_ALL
- ODDisposeHandle( containerHandle );
- RERAISE;
- ENDTRY
-
- return containerHandle;
- }
-
- static void CloneIntoFlavor(Environment* ev, ODDragAndDrop* dad, ODDragItem* theDragItem,
- ODPlatformDragReference theDrag, ItemReference theItem, FlavorType theType,
- FSSpec dropFSSpec)
- {
- OSErr result;
-
- if ((result = CloneIntoFile(ev, theDragItem, dropFSSpec)) == noErr)
- {
- result = SetDragItemFlavorData(theDrag, theItem, theType, &dropFSSpec, sizeof(FSSpec), 0L);
- }
- else
- {
- dad->SetDropResult(ev, kODDropFail);
- }
- }
-
- static OSErr CloneIntoFile(Environment* ev, ODDragItem* theDragItem, FSSpec dropFSSpec)
- {
- OSErr err = noErr;
- PlatformFile file;
- file.Specify(&dropFSSpec);
-
- TRY
- ODStorageUnit* contentSU = theDragItem->GetStorageUnit(ev);
- ODID targetContentFrameID = kODNULLID;
- OSType fileType = GetStorageUnitOSType(ev,contentSU);
- OSType fileCreator=ODGetIconFilePlatformCreatorFromPartSU(ev,contentSU);
-
- file.Create(fileCreator, fileType, smSystemScript);
- SetFinderInfo(ev, contentSU, &file);
- SetIconFamily(ev, contentSU, &file);
- TempODContainer targetContainer = CreateFileContainer(ev, contentSU->GetSession(ev), &file.GetFileSpec());
- TempODDocument targetDocument = targetContainer->AcquireDocument(ev, kODDefaultDocument);
- TempODDraft targetDraft = targetDocument->AcquireBaseDraft(ev, kODDPExclusiveWrite);
- TempODStorageUnit targetDraftProperties = targetDraft->AcquireDraftProperties(ev);
- TempODStorageUnit targetSU = targetDraft->CreateStorageUnit(ev);
- ODSetStrongSURefProp(ev, targetDraftProperties, kODPropRootPartSU,kODStrongStorageUnitRef, targetSU->GetID(ev));
- ODDraft* sourceDraft = contentSU->GetDraft(ev);
- ODDraftKey cloneKey = 0;
- TRY
- cloneKey = sourceDraft->BeginClone(ev, targetDraft, kODNULL, kODCloneToFile);
- sourceDraft->Clone(ev, cloneKey, contentSU->GetID(ev), targetSU->GetID(ev), 0);
- ODID contentFrameID = ODGetWeakSURefProp(ev, contentSU, kODPropContentFrame, kODWeakStorageUnitRef);
- if (contentFrameID != kODNULLID)
- {
- targetContentFrameID = sourceDraft->Clone(ev, cloneKey, contentFrameID, kODNULLID, 0);
- }
- sourceDraft->EndClone(ev, cloneKey);
- CATCH_ALL
- sourceDraft->AbortClone(ev, cloneKey);
- ENDTRY
-
- if (targetContentFrameID != kODNULLID)
- ODSetStrongSURefProp(ev, targetDraftProperties, kODPropRootFrameList, kODStrongStorageUnitRefs, targetContentFrameID);
-
- ODSURemoveProperty(ev, targetSU, kODPropMouseDownOffset);
-
- targetDraft->Externalize(ev);
- CATCH_ALL
-
- file.Delete();
- err = dragNotAcceptedErr;
- WARN("Error caught in CloneIntoFile.");
- ENDTRY
-
- return err;
- }
-
- static boolean MakeUniqueFilename( Environment *ev, ODSession* session, ODStorageUnit *su, FSSpec* spec )
- {
- const ODULong kODMaxFileNameSize = 63;
-
- Str255 prefix;
- prefix[0] = 0;
- boolean nameFromPart = false;
- TempPlatformFile file = new PlatformFile;
- file->Specify(spec);
-
- TRY
- // Get the name of the part
- if (su->Exists(ev, kODPropName, kODMacIText, 0))
- {
- ODIText* rootPartName = ODGetITextProp(ev, su, kODPropName, kODMacIText, kODNULL);
- if (rootPartName)
- {
- GetITextPString(rootPartName, prefix);
- DisposeIText(rootPartName);
- p2cstr(prefix);
- file->SetAsciiName((char*) prefix);
- nameFromPart = true;
- }
- }
-
- if (!prefix[0])
- {
- // Get the category of the part if a name cannot be found.
- ODName* categoryName = kODNULL;
- TRY
- categoryName = ODGetCatFromPartSU(ev, su, session->GetNameSpaceManager(ev));
- CATCH_ALL
- ENDTRY
- // If the above call throws, then most likely we were trying to get the category for NoPart.
- // So, set the category name for NoPart appropriately.
- if( !categoryName)
- {
- ODGetString( prefix, kODUnknownCategoryStr );
- p2cstr(prefix);
- }
- if (categoryName)
- {
- GetITextPString(categoryName, prefix);
- p2cstr(prefix);
- }
- file->SetAsciiName((char*) prefix);
- file->UniquifyName(kODNoResourceID,
- kODNULL,
- kODCategoryNumberSuffix,
- kODNULL,
- 1,
- kSpecifyNewNameOnly,
- kODForceNewName);
- ODDisposePtr(categoryName);
- nameFromPart = false;
- }
- CATCH_ALL
- ENDTRY
-
- *spec = file->GetFileSpec();
- return nameFromPart;
- }
-
- static OSType GetStorageUnitOSType( Environment *ev, ODStorageUnit *su )
- {
- OSType returnType = kODShellSignature;
-
- #if ODDebug_DragAndDrop
- ODULong numProperties = su->CountProperties(ev);
- su->Focus(ev, kODNULL, kODPosAll, kODNULL, 0, kODPosAll);
- for (ODULong i = 1; i <= numProperties; i++) {
- su->Focus(ev, kODNULL, kODPosNextSib,kODNULL,0,kODPosAll);
- ODPropertyName name = su->GetProperty(ev);
- ODDisposePtr(name);
- }
- #endif
-
- returnType = ODGetIconFilePlatformTypeFromPartSU(ev, su);
-
- return returnType;
- }
-
-
- static OSErr CopyToDragItemInChunks(Environment* ev,
- FlavorType theType,
- ItemReference theItem,
- ODPlatformDragReference theDrag,
- ODDragItem* theDragItem)
- {
- const ODULong kCopyBlockSize = 512;
- OSErr result = noErr;
- ODPtr dataPtr = ODNewPtr(kCopyBlockSize);
- ODULong dataSize = theDragItem->GetStorageUnit(ev)->GetSize(ev);
-
- ODULong currentByte = 0;
- while ((currentByte < dataSize) && (result == noErr)) {
- ODULong bytesRead = StorageUnitGetValue(theDragItem->GetStorageUnit(ev), ev, kCopyBlockSize, dataPtr);
- result = SetDragItemFlavorData(theDrag, theItem, theType, dataPtr, bytesRead, currentByte);
- WASSERTM(result == noErr, "Error from SetDragItemFlavorData in CopyToDragItemInChunks.");
- currentByte += bytesRead;
- }
- ODDisposePtr(dataPtr);
- WASSERTM(currentByte == dataSize, "Bytes written is NOT equal to dataSize.");
-
- return result;
- }
-
- static OSErr CopyFromDragItemInChunks(Environment* ev,
- FlavorType theType,
- ItemReference theItem,
- ODPlatformDragReference theDrag,
- ODStorageUnitView* destSUView)
- {
- const ODULong kCopyBlockSize = 512;
- OSErr result = noErr;
- ODPtr dataPtr = ODNewPtr(kCopyBlockSize);
- long dataSize = 0;
- ODULong totalRead = 0;
- ODULong oldValueSize = destSUView->GetSize(ev);
-
- result = GetFlavorDataSize(theDrag, theItem, theType, &dataSize);
- while ((totalRead < dataSize) && (result == noErr)) {
- Size bytesRead = dataSize - totalRead;
- if (bytesRead > kCopyBlockSize)
- bytesRead = kCopyBlockSize;
- result = GetFlavorData(theDrag, theItem, theType, dataPtr, &bytesRead, totalRead);
- WASSERTM(result == noErr, "Error from GetFlavorData in CopyFromDragItemInChunks.");
- StorageUnitViewSetValue(destSUView, ev, bytesRead, dataPtr);
- totalRead += bytesRead;
- }
- ODDisposePtr(dataPtr);
-
- ODULong newValueSize = destSUView->GetOffset(ev);
- if (oldValueSize > newValueSize)
- destSUView->DeleteValue(ev, oldValueSize - newValueSize);
-
- return result;
- }
-
-
- #ifdef ODDebug_DragAndDrop
- void PrintDragReference(ODPlatformDragReference dragRef, char* header)
- {
- unsigned short items = 0;
- CountDragItems(dragRef, &items);
- somPrintf("%s: fDragReference %x numItems %d\n", header, dragRef, items);
- for (unsigned short i = 1; i <= items; i++) {
- ItemReference itemRef;
- GetDragItemReferenceNumber(dragRef, i, &itemRef);
- unsigned short numFlavors = 0;
- CountDragItemFlavors(dragRef, itemRef, &numFlavors);
- FlavorType theType;
- Size dataSize = 0;
- for (unsigned short j = 1; j <= numFlavors; j++) {
- GetFlavorType (dragRef, itemRef, j, &theType);
- GetFlavorDataSize(dragRef, itemRef, theType, &dataSize);
- somPrintf("%s: itemRef %x item %d flavor %d size %d type ", header, itemRef, i, j, dataSize);
- for (short k = 0; k <= 3; k++) {
- somPrintf("%c", ((char*) &theType)[k]);
- }
- somPrintf("\n");
- if ((theType == 'hfs ') && (dataSize > 0)) {
- HFSFlavor hfsFlavor;
- GetFlavorData(dragRef,itemRef,theType,&hfsFlavor,&dataSize,0);
- somPrintf("type %x creator %x name %s\n", hfsFlavor.fileType, hfsFlavor.fileCreator, p2cstr(hfsFlavor.fileSpec.name));
- }
- }
- }
- }
-
- void PrintStorageUnit(Environment* ev, ODStorageUnit* su, char* header)
- {
- ODStorageUnitCursor* cursor = su->CreateCursorWithFocus(ev);
-
- ODULong numProperties = su->CountProperties(ev);
- su->Focus(ev, kODPropContents, kODPosUndefined, kODNULL, 0, kODPosUndefined);
- ODULong numValues = su->CountValues(ev);
- somPrintf("%s: su %x numProperties %d numContentValues %d\n", header, su, numProperties, numValues);
- for (short i = 1; i <= numValues; i++) {
- su->Focus(ev, kODNULL, kODPosSame, kODNULL, i, kODPosUndefined);
- ODValueType type = su->GetType(ev);
- somPrintf("%s: Type %d %s\n", header, i, type);
- ODDisposePtr(type);
- }
-
- su->FocusWithCursor(ev, cursor);
- delete cursor;
- }
-
- #endif
-
- SOM_Scope OSErr SOMLINK ODDragAndDropEnterHandler(ODDragAndDrop *somSelf, Environment *ev,
- ODPlatformDragReference theDrag)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropEnterHandler");
-
- #if ODDebug_DragAndDrop
- somPrintf("In EnterHandler.\n");
- #endif
-
- OSErr returnCode = noErr;
-
- ODVolatile(returnCode);
- SOM_TRY
- OSErr result = noErr;
- ODDragLink* newLink = kODNULL;
- ODUShort items = 0;
-
- CountDragItems(theDrag, &items);
- for (ODUShort i = 1; i <= items; ++i)
- {
- ItemReference itemID;
- FlavorFlags theFlags;
- result = GetDragItemReferenceNumber(theDrag, i, &itemID);
- result = GetFlavorFlags(theDrag, itemID, kODPromiseFlavor, &theFlags);
- if (result == noErr)
- {
- if (_fDragReference != theDrag)
- {
- _fListFromHandler = kODTrue;
- newLink = new ODDragLink((ODDragItem*)itemID, kODFalse);
- _fDragItemList->AddLast((Link*)newLink);
- }
- }
- else if (result == badDragFlavorErr)
- { ODStorageSystem* storage = _fStorageSystem;
- ODTranslation* translate = _fSession->GetTranslation(ev);
- ODDragItem* newItem = kODNULL; ODVolatile(newItem);
-
- ODUShort count;
- ODUShort j = 1;
- HFSFlavor* hfsFlavor = (HFSFlavor*)ODNewPtr( sizeof(HFSFlavor) );
- CountDragItemFlavors(theDrag, itemID, &count);
-
- // Do something special for: Bento files, Finder files, and data
- // interchange container types.
- for (j = 1; (j <= count) && (newItem == kODNULL); j++)
- { OSType theType;
- OSErr err = GetFlavorType(theDrag, itemID, j, &theType);
- if ((err == noErr) && (theType == flavorTypeHFS))
- {
- Size dataSize = sizeof(HFSFlavor);
- OSErr err = GetFlavorData(theDrag, itemID, theType, hfsFlavor,
- (Size*) &dataSize, 0);
- if (err == noErr)
- {
- FSSpec* targetFileSpec = &(hfsFlavor->fileSpec);
- if (IsOpenDocDocument(hfsFlavor))
- {
- // The item is a Bento file container; create the update container for it.
- // Later we will put the HFS info in it, even if it is a read-only file.
- ODBoolean wasAliased;
- ODBoolean targetIsFolder;
- OSErr err = ResolveAliasFile(targetFileSpec, TRUE, &targetIsFolder, &wasAliased);
- if ((err == noErr) && (!targetIsFolder)) {
- FInfo finderInfo;
- err = FSpGetFInfo(targetFileSpec, &finderInfo);
- if ((err == noErr) && IsOpenDocDocument(hfsFlavor /*finderInfo.fdType*/)) {
- ODByteArray* ba = CreateByteArray(targetFileSpec, sizeof(FSSpec));
- TRY
- newItem = new(ODGetDefaultHeap()) ODFileDragItem(storage, kODTrue,
- theDrag, itemID, hfsFlavor);
- ((ODFileDragItem*) newItem)->Initialize(ev, ba);
- CATCH_ALL
- delete newItem;
- newItem = kODNULL;
- ENDTRY
- DisposeByteArray(ba);
- }
- }
- }
- else if( IsOpenDocClipping( hfsFlavor ) )
- {
- // The user has dragged in a clipping that has Bento container data.
- // While we will get a drag flavor of type kODBentoFlavor that we could have
- // loaded in a later section just like the data had come from the Scrapbook,
- // the Finder won't resolve its promise for that data to the Drag Manager,
- // so we can't use the Drag Manager API to load the data.
- // Instead, we need to load the data directly from the clipping's resource fork.
-
- ODHandle tempHandle = kODNULL; ODVolatile( tempHandle );
-
- TRY
- tempHandle = ReadClippingFileOpenDocData( hfsFlavor );
- if( tempHandle == kODNULL )
- THROW( kODErrDragTrackingException );
- ODLockHandle( tempHandle );
- newItem = new(ODGetDefaultHeap()) ODMemDragItem(storage, tempHandle,
- kODTrue,theDrag, itemID, kODNULL);
- ODUnlockHandle(tempHandle);
- CATCH_ALL
- if( newItem )
- { ODDeleteObject( newItem ); }
- else
- {
- if( tempHandle != kODNULL )
- ODDisposeHandle( tempHandle );
- }
- RERAISE;
- ENDTRY
-
- }
- else
- { if( _fMemItemContainer == kODNULL)
- {
- ODHandle memContainerHandle = ODNewHandle(0);
- _fMemItemContainer = CreateMemoryContainer(ev, _fSession,
- memContainerHandle, kODBentoMemoryContainer);
- // _fMemItemContainer->Acquire(ev);
- ODDocument* theDocument = _fMemItemContainer->AcquireDocument( ev, kODDefaultDocument );
- _fCachedMemContainerDraft = theDocument->AcquireBaseDraft(ev, kODDPExclusiveWrite);
- // Refs to container/doc/draft will be released in Clear method.
- }
- newItem = new(ODGetDefaultHeap()) ODMemDragItem(storage, _fCachedMemContainerDraft,
- kODTrue, theDrag, itemID, hfsFlavor);
- ((ODMemDragItem*) newItem)->Initialize(ev);
- }
- }
- }
- if( theType == kODBentoFlavor )
- {
- // The item is a memory container handle that had been either:
- // a) Dragged to a non-OpenDoc process (like the Scrapbook) then dragged back.
- // b) Put on the Clipboard, pasted into non-OpenDoc process, then dragged back.
- // So, recreate the memory container.
- ODHandle tempHandle = kODNULL;
- ODVolatile( tempHandle );
- TRY
- Size flavorSize = 0;
-
- OSErr DragSizeErr = GetFlavorDataSize( theDrag, itemID, theType, &flavorSize );
- if( DragSizeErr != noErr )
- THROW( DragSizeErr );
- tempHandle = ODNewHandle( flavorSize );
- ODLockHandle( tempHandle );
- OSErr DragDataErr = GetFlavorData(theDrag, itemID, theType, *tempHandle, (Size*) &flavorSize, 0);
- if( DragDataErr != noErr )
- THROW( DragDataErr );
- ODUnlockHandle(tempHandle);
- newItem = new(ODGetDefaultHeap()) ODMemDragItem(storage, tempHandle,
- kODTrue,theDrag, itemID, kODNULL);
- CATCH_ALL
- if( newItem )
- { ODDeleteObject( newItem ); }
- else
- { ODDisposeHandle( tempHandle ); }
- if( MemError() != noErr || ErrorCode() != -1854 ) // -1854 = cantGetFlavorErr
- {
- RERAISE;
- // We could get error -1854 because we are trying to load data from a
- // clipping, and the Finder will not resolve drag promises at DragTrack time.
- // Therefor, we will load OpenDoc data from clippings in the routine
- // above in the hfs secion, and do not need to Reraise this error.
- // But, we do want to reraise it when we get it because we are out of memory,
- // which means that there really was an error loading the flavor data or
- // getting its size.
- }
- ENDTRY
- }
- }
- if (newItem == kODNULL)
- { // Otherwise, the item was neither a memory or file container.
- // Just make a new drag item for it. We will use one container to
- // hold all non-container data, and just create new storage units for
- // each new item.
- if( _fMemItemContainer == kODNULL ) {
- ODHandle memContainerHandle = ODNewHandle(0);
- _fMemItemContainer = CreateMemoryContainer(ev, _fSession,
- memContainerHandle, kODBentoMemoryContainer);
- // _fMemItemContainer->Acquire(ev);
- ODDocument* theDocument = _fMemItemContainer->AcquireDocument( ev, kODDefaultDocument );
- _fCachedMemContainerDraft = theDocument->AcquireBaseDraft(ev, kODDPExclusiveWrite);
- // Refs to container/doc/draft will be released in Clear method.
- }
- newItem = new(ODGetDefaultHeap()) ODMemDragItem(storage, _fCachedMemContainerDraft, kODTrue, theDrag,
- itemID, hfsFlavor);
- ((ODMemDragItem*) newItem)->Initialize(ev);
- }
- _fListFromHandler = kODTrue;
- newLink = new ODDragLink(newItem, kODTrue);
- _fDragItemList->AddLast((Link*)newLink);
- }
- else
- { WASSERTM(result == noErr, "Error from GetFlavorFlags in tracking handler");
- returnCode = result;
- break;
- }
- }
- _fDragReference = theDrag;
- _fAttributes = 0;
- if (_fListFromHandler)
- { LinkedListIterator* newIter = new LinkedListIterator(_fDragItemList);
- ODDragItemIterator* tmpIter = new ODDragItemIterator();
- THROW_IF_NULL(tmpIter, kODErrOutOfMemory);
- tmpIter->InitDragItemIterator(ev, newIter);
- _fDragItemIterator = tmpIter;
- }
-
- ODDeleteObject(_fFacetsRejected);
-
- SOM_CATCH_ALL
-
- returnCode = ErrorCode();
- ODDeleteObject(_fFacetsRejected);
- if (_fDragItemList)
- _fDragItemList->DeleteAllLinks();
-
- SOM_ENDTRY
-
- _fFacetsRejected = new OpenHashTable(OpenHashTable::StdEqual, OpenHashTable::StdHash, kODNULL);
- _fFacetsRejected->Initialize(kODInitialNumEntries,
- sizeof(ODFacet*),
- sizeof(ODFacet*));
-
- return returnCode;
- }
-
- SOM_Scope OSErr SOMLINK ODDragAndDropEnterWindow(ODDragAndDrop *somSelf, Environment *ev,
- ODPlatformDragReference theDrag,
- ODPlatformWindow theWindow)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropEnterWindow");
-
- // This is a private method called only from MyDragTrackingHandler.
- // It can do without its own SOM_TRY.
-
- #if ODDebug_DragAndDrop
- somPrintf("Enter EnterWindow.\n");
- #endif
-
- ODPoint mouse, localMouse;
- Point qdMouse;
- ODFacet* targetFacet = kODNULL;
- ODBoolean handled = kODFalse;
-
- GetDragMouse(theDrag, &qdMouse, 0L);
- mouse = qdMouse;
- targetFacet = somSelf->FindTargetFacet(ev, theWindow, &mouse, &localMouse);
-
- if (!targetFacet)
- _fAttributes &= kODDragHasLeftSourcePartMask;
- else
- {
- while (targetFacet && !handled)
- {
- if ((targetFacet->GetFrame(ev) == _fSourceFrame) && (_fHasLeftSourceFrame == kODFalse)) {
- _fAttributes |= kODDragIsInSourcePart;
- _fAttributes |= kODDragIsInSourceFrame;
- }
- else
- {
- _fHasLeftSourceFrame = kODTrue;
- ODPart* targetPart = targetFacet->GetFrame(ev)->AcquirePart(ev);
- if (targetPart == _fSourcePart)
- _fAttributes = kODDragIsInSourcePart;
- else {
- _fHasLeftSourcePart = kODTrue;
- _fAttributes = 0;
- }
- ODReleaseObject(ev, targetPart);
- }
- handled = targetFacet->DragEnter(ev, &localMouse, _fDragItemIterator, kODNULL);
- if (!handled)
- {
- _fFacetsRejected->ReplaceEntry(&targetFacet, &targetFacet);
- targetFacet = somSelf->FindTargetFacet(ev, theWindow, &mouse, &localMouse);
- }
- }
- }
- _fPrevFacet = targetFacet;
-
- return noErr;
- }
-
- SOM_Scope OSErr SOMLINK ODDragAndDropInWindow(ODDragAndDrop *somSelf, Environment *ev,
- ODPlatformDragReference theDrag,
- ODPlatformWindow theWindow)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropInWindow");
-
- ODPoint mouse, localMouse;
- Point qdMouse;
- ODFacet* targetFacet = kODNULL;
- ODBoolean handled = kODFalse;
-
- SOM_TRY
-
- GetDragMouse(theDrag, &qdMouse, 0L);
- mouse = qdMouse;
- // Get the facet under the current mouse location.
- targetFacet = somSelf->FindTargetFacet(ev, theWindow, &mouse, &localMouse);
-
- // We are leaving the window, call DragLeave on the last facet and return
- if (!targetFacet) {
- _fAttributes &= kODDragHasLeftSourcePartMask;
- if (_fPrevFacet) {
- _fPrevFacet->DragLeave(ev, &localMouse, kODNULL);
- }
- }
- // Otherwise, the mouse is still in the OpenDoc window.
- else
- {
- // Since the mouse is still in the OpenDoc window, we want to implement the following protocal for
- // having different facets draw drag highlighting. Everytime the mouse moves and is still in the window:
- // A. If the mouse enters a new facet, call DragEnter on the new one.
- // 1. If the new facet can't accept the drag, call DragEnter on the next containg facet.
- // B. If the mouse stays within the same facet, call DragWithin on that facet again.
- // C. If the mouse leaves a facet, call DragLeave on the facet.
- // We don't want drag-highlighiting to take place on the frame that originates the drag,
- // unless the mouse leaves the frame, then enters it again. So, we do the following:
- // 1. Store a refernce to the frame that originated the drag..
- // 2. Define a boolean that signifies that the mouse has not left the source frame.
- // 3. While the mouse is still in the source frame, tell the part not to do any drag-hiliting as above.
- // 4. When the mouse leaves the source frame, set the boolean that signifies we have not left the source
- // to false. This tells subsequent parts to do hilighting following the above algorithm.
-
- // We basically want to do one of the following in this loop:
- // 1. Track that the mouse has entered a new facet and call DragEnter on it.
- // 2. Track that the mouse has left a facet and call DragLeave on it.
- // 3. Track that the mouse is still in a facet and call DragWithin on it.
- // Obviously there are special cases to all of the above. See the source comments below for more info.
- while (targetFacet && !handled)
- {
- // Check whether we are still in the source frame, and haven't ever left it. If so, no hiliting needed.
- if ((targetFacet->GetFrame(ev) == _fSourceFrame) && (_fHasLeftSourceFrame == kODFalse)) {
- _fAttributes |= kODDragIsInSourcePart;
- _fAttributes |= kODDragIsInSourceFrame;
- }
- // Otherwise, we are either in a new frame, or we have left and reenter the source frame.
- // Tell the part to start doing hiliting.
- else {
- _fHasLeftSourceFrame = kODTrue;
- ODPart* targetPart = targetFacet->GetFrame(ev)->AcquirePart(ev);
- if (targetPart == _fSourcePart)
- _fAttributes = kODDragIsInSourcePart;
- else {
- _fHasLeftSourcePart = kODTrue;
- _fAttributes = 0;
- }
- ODReleaseObject(ev, targetPart);
- }
- if (_fPrevFacet == targetFacet) {
- handled = targetFacet->DragWithin(ev, &localMouse, _fDragItemIterator, kODNULL);
- }
- else {
- // We need to call DragLeave on the previous facet before we call DragEnter on the new one, even
- // though the DragEnter can return false. Why not call DragEnter first, decide if it succeeds, then
- // call DragLeave? Because of ShowDragHilite and HideDragHilite Drag Manager functions need this
- // order or drag hiliting is messed up.
- if( _fPrevFacet )
- _fPrevFacet->DragLeave(ev, &localMouse, kODNULL);
- handled = targetFacet->DragEnter(ev, &localMouse, _fDragItemIterator, kODNULL);
- // if ( _fPrevFacet && !handled ) {
- // targetFacet->DragEnter(ev, &localMouse, _fDragItemIterator, kODNULL);
- // }
- }
- if (!handled)
- {
- // If any facet rejects a particular drag, then at no time during the current will it ever
- // accept it again. A part can only handle certain drag kinds, and that will not change during
- // a drag. So, if a drag is rejected, keep a list of facets that have rejected the current
- // drag and don't try to do hiliting for them again for this drag.
- _fFacetsRejected->ReplaceEntry(&targetFacet, &targetFacet);
- // On of the following happened previous to this statement:
- // DragWithin or DragEnter was called on a facet and the part returned false.
- // So, give the container a crack at the drag.
- targetFacet = somSelf->FindTargetFacet(ev, theWindow, &mouse, &localMouse);
- if( targetFacet )
- targetFacet->DragEnter(ev, &localMouse, _fDragItemIterator, kODNULL);
- // else the root rejected the drag and there is no container to take the drag. Will just
- // exit this loop.
- }
- }
- }
- _fPrevFacet = targetFacet;
-
- SOM_CATCH_ALL
- SOM_ENDTRY
-
- return noErr;
- }
-
- SOM_Scope OSErr SOMLINK ODDragAndDropLeaveWindow(ODDragAndDrop *somSelf, Environment *ev,
- ODPlatformDragReference theDrag,
- ODPlatformWindow theWindow)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropLeaveWindow");
-
- #if ODDebug_DragAndDrop
- somPrintf("In LeaveWindow.\n");
- #endif
-
- SOM_TRY
- ODPoint mouse, localMouse;
- Point qdMouse;
-
- GetDragMouse(theDrag, &qdMouse, 0L);
- mouse = qdMouse;
- ODFacet* dummyTargetFacet = somSelf->FindTargetFacet(ev, theWindow, &mouse, &localMouse);
-
- _fAttributes = 0;
- if (_fPrevFacet) {
- _fPrevFacet->DragLeave(ev, &localMouse, kODNULL);
- _fPrevFacet = kODNULL;
- }
- SOM_CATCH_ALL
- SOM_ENDTRY
-
- _fHasLeftSourceFrame = kODTrue;
- _fHasLeftSourcePart = kODTrue;
-
- return noErr;
- }
-
- SOM_Scope OSErr SOMLINK ODDragAndDropLeaveHandler(ODDragAndDrop *somSelf, Environment *ev)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropLeaveHandler");
-
- #if ODDebug_DragAndDrop
- somPrintf("In LeaveHandler.\n");
- #endif
-
- // Now undo the damage done in the dragTrackingEnterHandler section.
- // NOTE: It is OK to blow away the drag items here because at this point
- // the drop handler will already have processed the drop if any.
- if (_fListFromHandler)
- {
- TRY{
- somSelf->Clear(ev);
- }CATCH_ALL{
- // ignore error
- }ENDTRY
- _fListFromHandler = kODFalse;
- _fDragReference = 0;
- }
- _fAttributes = 0;
-
- return noErr;
- }
-
- static void SetIconFamily(Environment* ev, ODStorageUnit* fromSU, PlatformFile* file)
- {
- static const ResType kIconType[6] = {'ICN#','icl4','icl8','ics#','ics4','ics8'};
- static const short kIconSize[6] = {256, 512, 1024, 64, 128, 256 };
- ODIconFamily icons = ODGetIconFamilyProp(ev, fromSU, kODPropCustomIcon, kODIconFamily, kAllIconsMask);
-
- if (icons)
- {
- // write icons to the file
- long i = 6;
- do {
- Handle icon;
- char state;
- if ((GetIconFromSuite(&icon, icons, kIconType[--i]) == noErr) && (icon != nil))
- {
- state = HGetState(icon);
- HLock(icon);
- WASSERT(GetHandleSize(icon) == kIconSize[i]);
- file->WriteResourcePtr(kIconType[i], kCustomIconResource, *icon, kIconSize[i]);
- HSetState(icon, state);
- }
- } while (i);
- file->SetCustomIcon(kODTrue);
- }
- }
-
- static void SetFinderInfo(Environment* ev, ODStorageUnit* su, PlatformFile* file)
- {
- InitDateInfo(ev, su);
- ODULong modDate = ODGetModificationDate(ev, su);
- ODULong creationDate = ODGetCreationDate(ev, su);
-
- file->CreateResFile();
- file->SetFileModDate(modDate);
- file->SetFileCreationDate(creationDate);
- // file->SetStationery(ODGetSUIsStationery(ev, su));
- }
-
- static OSErr GetDropFSSpec(ODPlatformDragReference theDrag, FSSpec &dropFSSpec)
- {
- AEDesc dropDescriptor;
-
- OSErr result = GetDropLocation(theDrag, &dropDescriptor);
- if ((result != noErr) ||
- (dropDescriptor.descriptorType == typeNull) ||
- (dropDescriptor.dataHandle == nil))
- {
- result = fnfErr; // Can't create a file unless we know where it goes!
- }
- else
- {
- AEDesc fssDescriptor;
- result = AECoerceDesc(&dropDescriptor, typeFSS, &fssDescriptor);
- AEDisposeDesc(&dropDescriptor);
- if (result == noErr) {
- ODBlockMove(*fssDescriptor.dataHandle, &dropFSSpec, sizeof(FSSpec));
- AEDisposeDesc(&fssDescriptor);
-
- // Use PBGetCatInfo to get the directoryID of the target directory.
- CInfoPBRec getInfoPB;
- getInfoPB.dirInfo.ioCompletion = 0L;
- getInfoPB.dirInfo.ioNamePtr = (StringPtr) &(dropFSSpec.name);
- getInfoPB.dirInfo.ioVRefNum = dropFSSpec.vRefNum;
- getInfoPB.dirInfo.ioFDirIndex = 0;
- getInfoPB.dirInfo.ioDrDirID = dropFSSpec.parID;
- result = PBGetCatInfoSync(&getInfoPB);
- if (result == noErr)
- {
- dropFSSpec.parID = getInfoPB.dirInfo.ioDrDirID;
- dropFSSpec.name[0] = 0;
- }
- }
- }
-
- return result;
- }
-
- static boolean IsTrashFolder(FSSpec dropFSSpec)
- {
- short trashVol;
- long trashDir;
-
- return (FindFolder(dropFSSpec.vRefNum,kTrashFolderType,kDontCreateFolder,&trashVol,&trashDir) == noErr) &&
- (trashVol==dropFSSpec.vRefNum) && (
- (trashDir==dropFSSpec.parID) );
-
- }
-
- static boolean IsFrontProcess()
- {
- ProcessSerialNumber myProcess, frontProcess;
- boolean inFront = false;
-
- GetCurrentProcess(&myProcess);
- GetFrontProcess(&frontProcess);
- SameProcess(&myProcess, &frontProcess, &inFront);
-
- return inFront;
- }
-
- static OSErr CreateReplaceFileEvent(Environment* ev,
- AppleEvent* replaceFileEvent,
- ODSession* session,
- ProcessSerialNumber* psn)
- {
- OSErr err = noErr;
- AEAddressDesc targetAddress;
- TempAEDesc tempTargetAddress = kODNULL;
-
- err = AECreateDesc(typeProcessSerialNumber, psn, sizeof(ProcessSerialNumber), &targetAddress);
-
- if (err == noErr)
- {
- err = AECreateAppleEvent(kODShellSignature, kODReplaceFileEventID,
- &targetAddress, kAutoGenerateReturnID,
- kAnyTransactionID, replaceFileEvent);
- AEDisposeDesc(&targetAddress);
- }
- if ( err == noErr )
- err = AEPutParamPtr(replaceFileEvent, kODSession, typeLongInteger,
- &session, sizeof(ODSession*));
- return err;
- }
-
- static OSErr SetupReplaceFileEvent(Environment* ev,
- AppleEvent* replaceFileEvent,
- FSSpec* sourceFileSpec,
- FSSpec* destFileSpec)
- {
- OSErr err = noErr;
- if (err == noErr)
- {
- err = AEPutParamPtr(replaceFileEvent, kODSourceFileSpec, typeFSS,
- sourceFileSpec, sizeof(FSSpec));
- }
- if ( err == noErr )
- err = AEPutParamPtr(replaceFileEvent, kODDestinationFileSpec, typeFSS,
- destFileSpec, sizeof(FSSpec));
-
- #ifdef ODDebug
- if (err != noErr)
- {
- WARN("Error in SetupReplaceFileEvent: %d", err);
- }
- #endif
-
- return err;
- }
-
- static OSErr SendReplaceFileEvent(AppleEvent* replaceFileEvent, ProcessSerialNumber* psn)
- {
- OSErr err;
- AppleEvent replyAppleEvent;
-
- SetFrontProcess(psn);
-
- // TempAEDesc tmpReplaceFileAppleEvent(replaceFileEvent);
- err = AESend(replaceFileEvent, &replyAppleEvent, kAENoReply | kAEInteractWithSelf,
- kAENormalPriority, kAEDefaultTimeout, NULL, NULL);
-
- #ifdef ODDebug
- if (err != noErr)
- {
- WARN("Error in SendReplaceFileEvent: %d", err);
- }
- #endif
-
- return err;
- }
-
- static OSErr DisposeReplaceFileEvent(AppleEvent* replaceFileEvent)
- {
- return AEDisposeDesc(replaceFileEvent);
- }
-
- static OSErr ODPascal ReplaceFileAEHandler(
- const AppleEvent* replaceFileEvent,
- AppleEvent* reply,
- long refCon)
- {
- OSErr err = noErr;
- DescType returnedType;
- Size actualSize;
- FSSpec sourceFileSpec;
- FSSpec destFileSpec;
- ODSession* session = kODNULL;
-
- err = AEGetParamPtr(replaceFileEvent, kODSession,
- typeLongInteger, &returnedType,
- &session, sizeof(ODSession*), &actualSize);
- WASSERTM(actualSize == sizeof(ODSession*), "Incorrect kODSession size");
-
- if (err == noErr)
- {
- err = AEGetParamPtr(replaceFileEvent, kODDestinationFileSpec,
- typeFSS, &returnedType,
- &destFileSpec, sizeof(FSSpec), &actualSize);
- WASSERTM(actualSize == sizeof(FSSpec), "Incorrect DestinationFileSpec size");
- }
-
- if (err == noErr)
- {
- Environment* ev = somGetGlobalEnvironment();
- ParamText(destFileSpec.name, "\p", "\p", "\p");
- err = AEInteractWithUser(kAEDefaultTimeout, NULL, NULL);
- if ((err == noErr) && ODAskUserReplace(ev, session))
- {
- err = AEGetParamPtr(replaceFileEvent, kODSourceFileSpec,
- typeFSS, &returnedType,
- &sourceFileSpec, sizeof(FSSpec), &actualSize);
- if (err == noErr)
- {
- WASSERTM(actualSize == sizeof(FSSpec), "Incorrect kODSourceFileSpec size");
- TempPlatformFile sourceFile = new PlatformFile;
- sourceFile->Specify(&sourceFileSpec);
- TempPlatformFile destFile = new PlatformFile;
- destFile->Specify(&destFileSpec);
-
- destFile->MoveToTrash();
- sourceFile->Move(destFileSpec.parID);
- }
- }
- }
-
- #ifdef ODDebug
- if (err != noErr)
- WARN("Error occured in ReplaceFileAEHandler: %d", err);
- #endif
-
- return err;
- }
-
- static void RespecifyToTempFolder(PlatformFile* file)
- {
- ODSLong tempDirID;
- FSSpec fsSpec = file->GetFileSpec();
-
- THROW_IF_ERROR(FindFolder(fsSpec.vRefNum, kTemporaryFolderType, kCreateFolder,
- &(fsSpec.vRefNum), &tempDirID));
- fsSpec.parID = tempDirID;
- file->Specify(&fsSpec);
- if (file->Exists())
- file->Delete();
- }
-
- static ODBoolean IsOpenDocDocument(HFSFlavor* hfsFlavor)
- {
- return PlatformFile::IsOpenDocDocument(hfsFlavor->fileType,hfsFlavor->fileCreator);
- }
-
- static ODBoolean IsOpenDocClipping( HFSFlavor* hfsFlavor)
- {
- ODBoolean isOpenDocClipping = kODFalse;
- OSType theFileType = hfsFlavor->fileType;
-
- // Check if the clipping came from the drag manager.
- if( hfsFlavor->fileCreator == 'drag' )
- {
- // Now check if it has the file type 'clp≈' where ≈ is any lower case letter.
- ODUByte* tempPtr = (ODUByte*)&theFileType;
- if( ( tempPtr[0] == 'c' ) && ( tempPtr[1] == 'l' ) &&
- ( tempPtr[2] == 'p' ) && ( islower( tempPtr[3] ) ) )
- {
- OSErr theErr;
- short oldResRefnum;
- short clippingRefNum;
- ODHandle tempHandle = kODNULL;
-
- // Now check if there is a resource of type kODBentoFlavor
- oldResRefnum = CurResFile();
- // Open the clipping's resource fork.
- SetResLoad(false); // Inside Mac says to make the SetResLoad calls before & after the OpenResFile call.
- // We probably don't need to do this in our case, but I'm paranoid today.
- clippingRefNum = FSpOpenResFile(&(hfsFlavor->fileSpec), fsCurPerm);
- SetResLoad(true);
- theErr = ResError();
- if( theErr == noErr )
- {
- short numODCN = Count1Resources(kODBentoFlavor);
- if( numODCN ==1 ) // the clipping has the Bento container data
- isOpenDocClipping = kODTrue;
- FSClose( clippingRefNum );
- }
- SetResLoad(true);
- UseResFile(oldResRefnum);
- }
- }
-
- return isOpenDocClipping;
- }
-
- static ODHandle ReadClippingFileOpenDocData( HFSFlavor* hfsFlavor )
- {
- OSErr theErr;
- short oldResRefnum;
- short clippingRefNum;
- ODHandle tempHandle = kODNULL;
-
- oldResRefnum = CurResFile();
- // Open the clipping's resource fork.
- SetResLoad(false); // Inside Mac says to make the SetResLoad calls before & after the OpenResFile call.
- clippingRefNum = FSpOpenResFile(&(hfsFlavor->fileSpec), fsCurPerm);
- SetResLoad(true); // We probably don't need to do this, but I'm paranoid today.
- theErr = ResError();
- if( theErr == noErr )
- {
- // The clipping has the data in a resource of the same name as the drag flavor, which
- // in our case is the the constant kODBentoFlavor.
- tempHandle = (ODHandle)BasicReadResource( clippingRefNum,kODBentoFlavor,1,kODNULL,1);
- FSClose( clippingRefNum );
- }
- if( theErr != noErr )
- {
- UseResFile(oldResRefnum);
- THROW( theErr );
- }
-
- UseResFile(oldResRefnum);
- return tempHandle;
- }
-