X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/e40298d54ecd5b109222a7c60aa2ef084a304d69..9e03e02d0ca493bc65f083600f1427d2ac8028ff:/src/mac/carbon/dnd.cpp diff --git a/src/mac/carbon/dnd.cpp b/src/mac/carbon/dnd.cpp index b9df2ac004..a84bce9196 100644 --- a/src/mac/carbon/dnd.cpp +++ b/src/mac/carbon/dnd.cpp @@ -9,11 +9,11 @@ // Licence: wxWindows licence /////////////////////////////////////////////////////////////////////////////// -#ifdef __GNUG__ +#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) #pragma implementation "dnd.h" #endif -#include "wx/defs.h" +#include "wx/wxprec.h" #if wxUSE_DRAG_AND_DROP @@ -24,6 +24,10 @@ #include "wx/gdicmn.h" #include "wx/mac/private.h" +#ifndef __DARWIN__ + #include +#endif + // ---------------------------------------------------------------------------- // global // ---------------------------------------------------------------------------- @@ -182,11 +186,25 @@ bool wxDropTarget::GetData() UInt16 flavors = 0 ; GetDragItemReferenceNumber((DragReference)m_currentDrag, index, &theItem); CountDragItemFlavors( (DragReference)m_currentDrag, theItem , &flavors ) ; + bool hasPreferredFormat = false ; + wxDataFormat preferredFormat = m_dataObject->GetPreferredFormat( wxDataObject::Set ) ; + for ( UInt16 flavor = 1 ; flavor <= flavors ; ++flavor ) { result = GetFlavorType((DragReference)m_currentDrag, theItem, flavor , &theType); wxDataFormat format(theType) ; - if ( m_dataObject->IsSupportedFormat( format ) ) + if ( preferredFormat == format ) + { + hasPreferredFormat = true ; + break ; + } + } + + for ( UInt16 flavor = 1 ; flavor <= flavors ; ++flavor ) + { + result = GetFlavorType((DragReference)m_currentDrag, theItem, flavor , &theType); + wxDataFormat format(theType) ; + if ( (hasPreferredFormat && format==preferredFormat) || (!hasPreferredFormat && m_dataObject->IsSupportedFormat( format ))) { FlavorFlags theFlags; result = GetFlavorFlags((DragReference)m_currentDrag, theItem, theType, &theFlags); @@ -195,34 +213,45 @@ bool wxDropTarget::GetData() Size dataSize ; Ptr theData ; GetFlavorDataSize((DragReference)m_currentDrag, theItem, theType, &dataSize); - if ( theType == 'TEXT' ) + if ( theType == kScrapFlavorTypeText ) { // this increment is only valid for allocating, on the next GetFlavorData // call it is reset again to the original value dataSize++ ; } + else if ( theType == kScrapFlavorTypeUnicode ) + { + // this increment is only valid for allocating, on the next GetFlavorData + // call it is reset again to the original value + dataSize++ ; + dataSize++ ; + } theData = new char[dataSize]; GetFlavorData((DragReference)m_currentDrag, theItem, theType, (void*) theData, &dataSize, 0L); - if( theType == 'TEXT' ) + if( theType == kScrapFlavorTypeText ) { - theData[dataSize]=0 ; - if ( wxApp::s_macDefaultEncodingIsPC ) - { - wxMacConvertToPC((char*)theData,(char*)theData,dataSize) ; - } - m_dataObject->SetData( format, dataSize, theData ); + theData[dataSize]=0 ; + m_dataObject->SetData( wxDataFormat(wxDF_TEXT), dataSize , theData ); + } + #if wxUSE_UNICODE + else if ( theType == kScrapFlavorTypeUnicode ) + { + theData[dataSize]=0 ; + theData[dataSize+1]=0 ; + m_dataObject->SetData( wxDataFormat(wxDF_UNICODETEXT), dataSize , theData ); } + #endif else if ( theType == kDragFlavorTypeHFS ) { HFSFlavor* theFile = (HFSFlavor*) theData ; wxString name = wxMacFSSpec2MacFilename( &theFile->fileSpec ) ; - if ( firstFileAdded ) - ((wxFileDataObject*)m_dataObject)->AddFile( name ) ; - else + if ( !firstFileAdded ) { - ((wxFileDataObject*)m_dataObject)->SetData( 0 , name.c_str() ) ; + // reset file list + ((wxFileDataObject*)m_dataObject)->SetData( 0 , "" ) ; firstFileAdded = true ; } + ((wxFileDataObject*)m_dataObject)->AddFile( name ) ; } else { @@ -246,9 +275,10 @@ bool wxDropTarget::GetData() // drag request wxDropSource::wxDropSource(wxWindow *win, - const wxIcon &iconCopy, - const wxIcon &iconMove, - const wxIcon &iconNone) + const wxCursor &cursorCopy, + const wxCursor &cursorMove, + const wxCursor &cursorStop) + : wxDropSourceBase(cursorCopy, cursorMove, cursorStop) { wxMacEnsureTrackingHandlersInstalled() ; m_window = win; @@ -256,9 +286,10 @@ wxDropSource::wxDropSource(wxWindow *win, wxDropSource::wxDropSource(wxDataObject& data, wxWindow *win, - const wxIcon &iconCopy, - const wxIcon &iconMove, - const wxIcon &iconNone) + const wxCursor &cursorCopy, + const wxCursor &cursorMove, + const wxCursor &cursorStop) + : wxDropSourceBase(cursorCopy, cursorMove, cursorStop) { wxMacEnsureTrackingHandlersInstalled() ; SetData( data ); @@ -270,7 +301,7 @@ wxDropSource::~wxDropSource() } -wxDragResult wxDropSource::DoDragDrop(int WXUNUSED(flags)) +wxDragResult wxDropSource::DoDragDrop(int flags) { wxASSERT_MSG( m_data, wxT("Drop source: no data") ); @@ -298,14 +329,18 @@ wxDragResult wxDropSource::DoDragDrop(int WXUNUSED(flags)) Ptr dataPtr = new char[dataSize] ; m_data->GetDataHere( formats[i] , dataPtr ) ; OSType type = formats[i].GetFormatId() ; - if ( type == 'TEXT' ) + if ( type == 'TEXT' || type == 'utxt' ) { - dataSize-- ; - if ( wxApp::s_macDefaultEncodingIsPC ) + if ( dataSize > 0 ) + dataSize-- ; + dataPtr[ dataSize ] = 0 ; + if ( type == 'utxt' ) { - wxMacConvertFromPC((char*)dataPtr,(char*)dataPtr,dataSize) ; + if ( dataSize > 0 ) + dataSize-- ; + dataPtr[ dataSize ] = 0 ; } - AddDragItemFlavor(theDrag, theItem, type , dataPtr, dataSize, 0); + AddDragItemFlavor(theDrag, theItem, type , dataPtr, dataSize, 0); } else if (type == kDragFlavorTypeHFS ) { @@ -313,7 +348,7 @@ wxDragResult wxDropSource::DoDragDrop(int WXUNUSED(flags)) OSErr err = noErr; CInfoPBRec cat; - wxMacFilename2FSSpec( dataPtr , &theFlavor.fileSpec ) ; + wxMacFilename2FSSpec( wxString( dataPtr , *wxConvCurrent ) , &theFlavor.fileSpec ) ; cat.hFileInfo.ioNamePtr = theFlavor.fileSpec.name; cat.hFileInfo.ioVRefNum = theFlavor.fileSpec.vRefNum; @@ -380,7 +415,29 @@ wxDragResult wxDropSource::DoDragDrop(int WXUNUSED(flags)) DisposeDrag(theDrag); gTrackingGlobals.m_currentSource = NULL ; - return wxDragCopy ; + bool optionDown = GetCurrentKeyModifiers() & optionKey ; + wxDragResult dndresult = wxDragCopy ; + if ( flags != wxDrag_CopyOnly ) + { + // on mac the option key is always the indication for copy + dndresult = optionDown ? wxDragCopy : wxDragMove; + } + return dndresult; +} + +bool wxDropSource::MacInstallDefaultCursor(wxDragResult effect) +{ + const wxCursor& cursor = GetCursor(effect); + if ( cursor.Ok() ) + { + cursor.MacInstall() ; + + return TRUE; + } + else + { + return FALSE; + } } bool gTrackingGlobalsInstalled = false ; @@ -416,6 +473,10 @@ pascal OSErr wxMacWindowDragTrackingHandler(DragTrackingMessage theMessage, Wind DragAttributes attributes; GetDragAttributes(theDrag, &attributes); wxTopLevelWindowMac* toplevel = wxFindWinFromMacWindow( theWindow ) ; + + bool optionDown = GetCurrentKeyModifiers() & optionKey ; + wxDragResult result = optionDown ? wxDragCopy : wxDragMove; + switch(theMessage) { case kDragTrackingEnterHandler: @@ -433,16 +494,23 @@ pascal OSErr wxMacWindowDragTrackingHandler(DragTrackingMessage theMessage, Wind GetDragMouse(theDrag, &mouse, 0L); localMouse = mouse; GlobalToLocal(&localMouse); + + -// if (attributes & kDragHasLeftSenderWindow) { - wxPoint point(localMouse.h , localMouse.v) ; wxWindow *win = NULL ; - toplevel->MacGetWindowFromPointSub( point , &win ) ; + ControlPartCode controlPart ; + ControlRef control = wxMacFindControlUnderMouse( toplevel , localMouse , + theWindow , &controlPart ) ; + if ( control ) + win = wxFindControlFromMacControl( control ) ; + else + win = toplevel ; + int localx , localy ; localx = localMouse.h ; localy = localMouse.v ; - //TODO : should we use client coordinates + if ( win ) win->MacRootWindowToWindow( &localx , &localy ) ; if ( win != trackingGlobals->m_currentTargetWindow ) @@ -464,19 +532,26 @@ pascal OSErr wxMacWindowDragTrackingHandler(DragTrackingMessage theMessage, Wind // this window is entered trackingGlobals->m_currentTargetWindow = win ; trackingGlobals->m_currentTarget = win->GetDropTarget() ; - if ( trackingGlobals->m_currentTarget ) { - trackingGlobals->m_currentTarget->SetCurrentDrag( theDrag ) ; - if ( trackingGlobals->m_currentTarget->OnEnter( - localx , localy , wxDragCopy ) != wxDragNone ) + + if ( trackingGlobals->m_currentTarget ) + { + trackingGlobals->m_currentTarget->SetCurrentDrag( theDrag ) ; + result = trackingGlobals->m_currentTarget->OnEnter( + localx , localy , result ) ; + } + + + if ( result != wxDragNone ) { - int x , y ; - x = y = 0 ; - win->MacWindowToRootWindow( &x , &y ) ; - RgnHandle hiliteRgn = NewRgn() ; - SetRectRgn( hiliteRgn , x , y , x+win->GetSize().x ,y+win->GetSize().y) ; - ShowDragHilite(theDrag, hiliteRgn, true); - DisposeRgn( hiliteRgn ) ; + int x , y ; + x = y = 0 ; + win->MacWindowToRootWindow( &x , &y ) ; + RgnHandle hiliteRgn = NewRgn() ; + Rect r = { y , x , y+win->GetSize().y , x+win->GetSize().x } ; + RectRgn( hiliteRgn , &r ) ; + ShowDragHilite(theDrag, hiliteRgn, true); + DisposeRgn( hiliteRgn ) ; } } } @@ -487,12 +562,46 @@ pascal OSErr wxMacWindowDragTrackingHandler(DragTrackingMessage theMessage, Wind { trackingGlobals->m_currentTarget->SetCurrentDrag( theDrag ) ; trackingGlobals->m_currentTarget->OnDragOver( - localx , localy , wxDragCopy ) ; + localx , localy , result ) ; } } + + // set cursor for OnEnter and OnDragOver + if ( trackingGlobals->m_currentSource && trackingGlobals->m_currentSource->GiveFeedback( result ) == FALSE ) + { + if ( trackingGlobals->m_currentSource->MacInstallDefaultCursor( result ) == FALSE ) + { + switch( result ) + { + case wxDragCopy : + { + wxCursor cursor(wxCURSOR_COPY_ARROW) ; + cursor.MacInstall() ; + } + break ; + case wxDragMove : + { + wxCursor cursor(wxCURSOR_ARROW) ; + cursor.MacInstall() ; + } + break ; + case wxDragNone : + { + wxCursor cursor(wxCURSOR_NO_ENTRY) ; + cursor.MacInstall() ; + } + break ; + + case wxDragError: + case wxDragLink: + case wxDragCancel: + // put these here to make gcc happy + ; + } + } + } - } - // MyTrackItemUnderMouse(localMouse, theWindow); + } break; case kDragTrackingLeaveWindow: if (trackingGlobals->m_currentTarget) @@ -529,7 +638,9 @@ pascal OSErr wxMacWindowDragReceiveHandler(WindowPtr theWindow, trackingGlobals->m_currentTargetWindow->MacRootWindowToWindow( &localx , &localy ) ; if ( trackingGlobals->m_currentTarget->OnDrop( localx , localy ) ) { - trackingGlobals->m_currentTarget->OnData( localx , localy , wxDragCopy ) ; + bool optionDown = GetCurrentKeyModifiers() & optionKey ; + wxDragResult result = optionDown ? wxDragCopy : wxDragMove; + trackingGlobals->m_currentTarget->OnData( localx , localy , result ) ; } } return(noErr);