]> git.saurik.com Git - wxWidgets.git/blobdiff - src/mac/carbon/dnd.cpp
Added extra width for controls to avoid edge being clipped
[wxWidgets.git] / src / mac / carbon / dnd.cpp
index 808dc49fa4296211ab8c87454ad356d114687b09..6f5a325730d958ad9d86d8e4b46e8fbfeac7f4ac 100644 (file)
@@ -1,5 +1,5 @@
 ///////////////////////////////////////////////////////////////////////////////
-// Name:        dnd.cpp
+// Name:        src/mac/carbon/dnd.cpp
 // Purpose:     wxDropTarget, wxDropSource implementations
 // Author:      Stefan Csomor
 // Modified by:
 #if wxUSE_DRAG_AND_DROP
 
 #include "wx/dnd.h"
-#include "wx/window.h"
-#include "wx/toplevel.h"
-#include "wx/app.h"
-#include "wx/gdicmn.h"
+
+#ifndef WX_PRECOMP
+    #include "wx/app.h"
+    #include "wx/toplevel.h"
+    #include "wx/gdicmn.h"
+#endif // WX_PRECOMP
+
 #include "wx/mac/private.h"
 
 #ifndef __DARWIN__
@@ -34,8 +37,9 @@ typedef struct
     wxWindow *m_currentTargetWindow;
     wxDropTarget *m_currentTarget;
     wxDropSource *m_currentSource;
-}
-MacTrackingGlobals;
+    wxDragResult m_result;
+    int m_flags;
+} MacTrackingGlobals;
 
 MacTrackingGlobals gTrackingGlobals;
 
@@ -109,7 +113,6 @@ bool wxDropTarget::CurrentDragHasSupportedFormat()
     if ( !supported )
     {
         UInt16 items;
-        OSErr result;
         ItemReference theItem;
         FlavorType theType;
         UInt16 flavors = 0;
@@ -123,7 +126,7 @@ bool wxDropTarget::CurrentDragHasSupportedFormat()
 
             for ( UInt16 flavor = 1; flavor <= flavors; ++flavor )
             {
-                result = GetFlavorType( (DragReference)m_currentDrag, theItem, flavor, &theType );
+                GetFlavorType( (DragReference)m_currentDrag, theItem, flavor, &theType );
                 if ( m_dataObject->IsSupportedFormat( wxDataFormat( theType ) ) )
                 {
                     supported = true;
@@ -188,7 +191,7 @@ bool wxDropTarget::GetData()
         FlavorType theType;
         FlavorFlags theFlags;
         UInt16 flavors;
-        bool firstFileAdded = false;
+        wxString filenamesPassed;
 
         CountDragItems( (DragReference)m_currentDrag, &items );
         for (UInt16 index = 1; index <= items; ++index)
@@ -199,22 +202,22 @@ bool wxDropTarget::GetData()
             wxDataFormat preferredFormat = m_dataObject->GetPreferredFormat( wxDataObject::Set );
             bool hasPreferredFormat = false;
 
-            for ( UInt16 flavor = 1; flavor <= flavors; ++flavor )
+            for (UInt16 flavor = 1; flavor <= flavors; ++flavor)
             {
                 result = GetFlavorType( (DragReference)m_currentDrag, theItem, flavor, &theType );
                 wxDataFormat format( theType );
-                if ( preferredFormat == format )
+                if (preferredFormat == format)
                 {
                     hasPreferredFormat = true;
                     break;
                 }
             }
 
-            for ( UInt16 flavor = 1; flavor <= flavors; ++flavor )
+            for (UInt16 flavor = 1; flavor <= flavors; ++flavor)
             {
                 result = GetFlavorType( (DragReference)m_currentDrag, theItem, flavor, &theType );
                 wxDataFormat format( theType );
-                if ( (hasPreferredFormat && format == preferredFormat)
+                if ((hasPreferredFormat && format == preferredFormat)
                     || (!hasPreferredFormat && m_dataObject->IsSupportedFormat( format )))
                 {
                     result = GetFlavorFlags( (DragReference)m_currentDrag, theItem, theType, &theFlags );
@@ -224,13 +227,13 @@ bool wxDropTarget::GetData()
                         Ptr theData;
 
                         GetFlavorDataSize( (DragReference)m_currentDrag, theItem, theType, &dataSize );
-                        if ( theType == kScrapFlavorTypeText )
+                        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 )
+                        else if (theType == kScrapFlavorTypeUnicode)
                         {
                             // this increment is only valid for allocating:
                             // on the next GetFlavorData call it is reset again to the original value
@@ -243,7 +246,7 @@ bool wxDropTarget::GetData()
                         else
                             theData = NULL;
 
-                        GetFlavorData( (DragReference)m_currentDrag, theItem, theType, (void*) theData, &dataSize, 0L );
+                        GetFlavorData( (DragReference)m_currentDrag, theItem, theType, (void*)theData, &dataSize, 0L );
                         switch (theType)
                         {
                         case kScrapFlavorTypeText:
@@ -260,28 +263,18 @@ bool wxDropTarget::GetData()
 #endif
 
                         case kDragFlavorTypeHFS:
+                            if (theData != NULL)
                             {
-                                wxFileDataObject *fdo = dynamic_cast<wxFileDataObject*>(m_dataObject);
-                                wxASSERT( fdo != NULL );
-
-                                if ((theData != NULL) && (fdo != NULL))
-                                {
-                                    HFSFlavor* theFile = (HFSFlavor*) theData;
-                                    wxString name = wxMacFSSpec2MacFilename( &theFile->fileSpec );
-
-                                    if ( !firstFileAdded )
-                                    {
-                                        // reset file list
-                                        fdo->SetData( 0, "" );
-                                        firstFileAdded = true;
-                                    }
-
-                                    if (!name.IsEmpty())
-                                        fdo->AddFile( name );
-                                }
+                                HFSFlavor* theFile = (HFSFlavor*)theData;
+#ifndef __LP64__
+                                wxString name = wxMacFSSpec2MacFilename( &theFile->fileSpec );
+
+                                if (!name.empty())
+                                    filenamesPassed += name + wxT("\n");
+#endif
                             }
                             break;
+
                         default:
                             m_dataObject->SetData( format, dataSize, theData );
                             break;
@@ -293,6 +286,12 @@ bool wxDropTarget::GetData()
                 }
             }
         }
+
+        if (filenamesPassed.length() > 0)
+        {
+            wxCharBuffer buf = filenamesPassed.fn_str();
+            m_dataObject->SetData( wxDataFormat(wxDF_FILENAME), strlen( buf ), (const char*)buf );
+        }
     }
 
     return true;
@@ -337,22 +336,20 @@ wxDragResult wxDropSource::DoDragDrop(int flags)
 {
     wxASSERT_MSG( m_data, wxT("Drop source: no data") );
 
-    if (!m_data)
-        return (wxDragResult) wxDragNone;
-    if (m_data->GetFormatCount() == 0)
-        return (wxDragResult) wxDragNone;
+    if ((m_data == NULL) || (m_data->GetFormatCount() == 0))
+        return (wxDragResult)wxDragNone;
 
-    OSStatus result;
     DragReference theDrag;
     RgnHandle dragRegion;
-    if ((result = NewDrag(&theDrag)) != noErr)
+
+    if (NewDrag( &theDrag ) != noErr)
         return wxDragNone;
 
     // add data to drag
     size_t formatCount = m_data->GetFormatCount();
     wxDataFormat *formats = new wxDataFormat[formatCount];
     m_data->GetAllFormats( formats );
-    ItemReference theItem = 1;
+    ItemReference theItem = (ItemReference) 1;
 
     for ( size_t i = 0; i < formatCount; ++i )
     {
@@ -378,6 +375,7 @@ wxDragResult wxDropSource::DoDragDrop(int flags)
         {
             HFSFlavor  theFlavor;
             OSErr err = noErr;
+#ifndef __LP64__
             CInfoPBRec cat;
 
             wxMacFilename2FSSpec( wxString( dataPtr, *wxConvCurrent ), &theFlavor.fileSpec );
@@ -388,8 +386,10 @@ wxDragResult wxDropSource::DoDragDrop(int flags)
             cat.hFileInfo.ioDirID = theFlavor.fileSpec.parID;
             cat.hFileInfo.ioFDirIndex = 0;
             err = PBGetCatInfoSync( &cat );
-            if (err == noErr)
+#endif
+          if (err == noErr)
             {
+#ifndef __LP64__
                 theFlavor.fdFlags = cat.hFileInfo.ioFlFndrInfo.fdFlags;
                 if (theFlavor.fileSpec.parID == fsRtParID)
                 {
@@ -406,7 +406,7 @@ wxDragResult wxDropSource::DoDragDrop(int flags)
                     theFlavor.fileCreator = cat.hFileInfo.ioFlFndrInfo.fdCreator;
                     theFlavor.fileType = cat.hFileInfo.ioFlFndrInfo.fdType;
                 }
-
+#endif
                 AddDragItemFlavor( theDrag, theItem, type, &theFlavor, sizeof(theFlavor), 0 );
             }
         }
@@ -428,11 +428,9 @@ wxDragResult wxDropSource::DoDragDrop(int flags)
 #if !TARGET_CARBON // TODO
     ev = (EventRecord*) wxTheApp->MacGetCurrentEvent();
 #else
-    {
-        EventRecord rec;
-        ev = &rec;
-        wxMacConvertEventToRecord( (EventRef) wxTheApp->MacGetCurrentEvent(), &rec );
-    }
+    EventRecord rec;
+    ev = &rec;
+    wxMacConvertEventToRecord( (EventRef) wxTheApp->MacGetCurrentEvent(), &rec );
 #endif
 
     const short dragRegionOuterBoundary = 10;
@@ -459,18 +457,15 @@ wxDragResult wxDropSource::DoDragDrop(int flags)
     // only when drag was successfully completed
 
     gTrackingGlobals.m_currentSource = this;
-    result = TrackDrag( theDrag, ev, dragRegion );
+    gTrackingGlobals.m_result = wxDragNone;
+    gTrackingGlobals.m_flags = flags;
+
+    TrackDrag( theDrag, ev, dragRegion );
     DisposeRgn( dragRegion );
     DisposeDrag( theDrag );
     gTrackingGlobals.m_currentSource = NULL;
 
-    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;
+    return gTrackingGlobals.m_result;
 }
 
 bool wxDropSource::MacInstallDefaultCursor(wxDragResult effect)
@@ -550,7 +545,7 @@ pascal OSErr wxMacWindowDragTrackingHandler(
 
             GetDragMouse( theDrag, &mouse, 0L );
             localMouse = mouse;
-            GlobalToLocal( &localMouse );
+            wxMacGlobalToLocal( theWindow, &localMouse );
 
             {
                 wxWindow *win = NULL;
@@ -575,7 +570,9 @@ pascal OSErr wxMacWindowDragTrackingHandler(
                         // this window is left
                         if ( trackingGlobals->m_currentTarget )
                         {
+#ifndef __LP64__
                             HideDragHilite( theDrag );
+#endif
                             trackingGlobals->m_currentTarget->SetCurrentDrag( theDrag );
                             trackingGlobals->m_currentTarget->OnLeave();
                             trackingGlobals->m_currentTarget = NULL;
@@ -604,7 +601,9 @@ pascal OSErr wxMacWindowDragTrackingHandler(
                                 RgnHandle hiliteRgn = NewRgn();
                                 Rect r = { y, x, y + win->GetSize().y, x + win->GetSize().x };
                                 RectRgn( hiliteRgn, &r );
+#ifndef __LP64__
                                 ShowDragHilite( theDrag, hiliteRgn, true );
+#endif
                                 DisposeRgn( hiliteRgn );
                             }
                         }
@@ -624,27 +623,20 @@ pascal OSErr wxMacWindowDragTrackingHandler(
                 {
                   if ( !trackingGlobals->m_currentSource->MacInstallDefaultCursor( result ) )
                   {
-                      switch ( result )
+                      int cursorID = wxCURSOR_NONE;
+
+                      switch (result)
                       {
                           case wxDragCopy:
-                              {
-                                  wxCursor cursor(wxCURSOR_COPY_ARROW);
-                                  cursor.MacInstall();
-                              }
+                              cursorID = wxCURSOR_COPY_ARROW;
                               break;
 
                           case wxDragMove:
-                              {
-                                  wxCursor cursor(wxCURSOR_ARROW);
-                                  cursor.MacInstall();
-                              }
+                              cursorID = wxCURSOR_ARROW;
                               break;
 
                           case wxDragNone:
-                              {
-                                  wxCursor cursor(wxCURSOR_NO_ENTRY);
-                                  cursor.MacInstall();
-                              }
+                              cursorID = wxCURSOR_NO_ENTRY;
                               break;
 
                           case wxDragError:
@@ -654,6 +646,12 @@ pascal OSErr wxMacWindowDragTrackingHandler(
                               // put these here to make gcc happy
                               ;
                       }
+
+                      if (cursorID != wxCURSOR_NONE)
+                      {
+                          wxCursor cursor( cursorID );
+                          cursor.MacInstall();
+                      }
                    }
                 }
             }
@@ -667,7 +665,9 @@ pascal OSErr wxMacWindowDragTrackingHandler(
             {
                 trackingGlobals->m_currentTarget->SetCurrentDrag( theDrag );
                 trackingGlobals->m_currentTarget->OnLeave();
+#ifndef __LP64__
                 HideDragHilite( theDrag );
+#endif
                 trackingGlobals->m_currentTarget = NULL;
             }
             trackingGlobals->m_currentTargetWindow = NULL;
@@ -694,7 +694,7 @@ pascal OSErr wxMacWindowDragReceiveHandler(
         trackingGlobals->m_currentTarget->SetCurrentDrag( theDrag );
         GetDragMouse( theDrag, &mouse, 0L );
         localMouse = mouse;
-        GlobalToLocal( &localMouse );
+        wxMacGlobalToLocal( theWindow, &localMouse );
         localx = localMouse.h;
         localy = localMouse.v;
 
@@ -703,13 +703,20 @@ pascal OSErr wxMacWindowDragReceiveHandler(
             trackingGlobals->m_currentTargetWindow->MacRootWindowToWindow( &localx, &localy );
         if ( trackingGlobals->m_currentTarget->OnDrop( localx, localy ) )
         {
-            bool optionDown = GetCurrentKeyModifiers() & optionKey;
-            wxDragResult result = optionDown ? wxDragCopy : wxDragMove;
-            trackingGlobals->m_currentTarget->OnData( localx, localy, result );
+            // the option key indicates copy in Mac UI, if it's not pressed do
+            // move by default if it's allowed at all
+            wxDragResult
+                result = !(trackingGlobals->m_flags & wxDrag_AllowMove) ||
+                            (GetCurrentKeyModifiers() & optionKey)
+                            ? wxDragCopy
+                            : wxDragMove;
+            trackingGlobals->m_result =
+                trackingGlobals->m_currentTarget->OnData( localx, localy, result );
         }
     }
 
     return noErr;
 }
 
-#endif
+#endif // wxUSE_DRAG_AND_DROP
+