]> git.saurik.com Git - wxWidgets.git/commitdiff
changed DoDragDrop(bool) into DoDragDrop(int) and added support for wxDrag_DefaultMov...
authorVadim Zeitlin <vadim@wxwidgets.org>
Sun, 28 Apr 2002 14:30:54 +0000 (14:30 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sun, 28 Apr 2002 14:30:54 +0000 (14:30 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@15297 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

18 files changed:
docs/latex/wx/dropsrc.tex
include/wx/dnd.h
include/wx/gtk/dnd.h
include/wx/gtk1/dnd.h
include/wx/mac/dnd.h
include/wx/motif/dnd.h
include/wx/msw/ole/dropsrc.h
include/wx/os2/dnd.h
include/wx/x11/dnd.h
samples/dnd/dnd.cpp
src/gtk/dnd.cpp
src/gtk1/dnd.cpp
src/mac/carbon/dnd.cpp
src/mac/dnd.cpp
src/motif/dnd.cpp
src/msw/ole/dropsrc.cpp
src/os2/dnd.cpp
src/x11/dnd.cpp

index 9b306331ee9aa27e9347218c0f8c3a7493474cb6..6223ea5e8825f760ab420fa8cdc5e6acda8e50a5 100644 (file)
@@ -76,11 +76,23 @@ drop source. This will not delete any previously associated data.
 
 \membersection{wxDropSource::DoDragDrop}\label{wxdropsourcedodragdrop}
 
-\func{virtual wxDragResult}{DoDragDrop}{\param{bool }{allowMove = FALSE}}
+\func{virtual wxDragResult}{DoDragDrop}{\param{int }{flags = {\tt wxDrag\_CopyOnly}}}
 
-Do it (call this in response to a mouse button press, for example).
+Do it (call this in response to a mouse button press, for example). This starts
+the drag-and-drop operation which will terminate when the user releases the
+mouse.
 
-If {\bf allowMove} is FALSE, data can only be copied.
+\wxheading{Parameters}
+
+\docparam{flags}{If {\tt wxDrag\_AllowMove} is included in the flags, data may
+be moved and not only copied (default). If {\tt wxDrag\_DefaultMove} is
+specified (which includes the previous flag), this is even the default
+operation}.
+
+\wxheading{Return value}
+
+Returns the operation requested by the user, may be {\tt wxDragCopy}, {\tt
+wxDragMove}, {\tt wxDragCancel} or {\tt wxDragNone} if an error occured.
 
 \membersection{wxDropSource::GiveFeedback}\label{wxdropsourcegivefeedback}
 
index 61f7625876e2d4ef4a025c0f57edab6cb53083fa..7ce567f72639d083200e433eca21a65cee8c9a83 100644 (file)
 // constants
 // ----------------------------------------------------------------------------
 
+// flags for wxDropSource::DoDragDrop()
+//
+// NB: wxDrag_CopyOnly must be 0 (== FALSE) and wxDrag_AllowMove must be 1
+//     (== TRUE) for compatibility with the old DoDragDrop(bool) method!
+enum
+{
+    wxDrag_CopyOnly    = 0, // allow only copying
+    wxDrag_AllowMove   = 1, // allow moving (copying is always allowed)
+    wxDrag_DefaultMove = 3  // the default operation is move, not copy
+};
+
 // result of wxDropSource::DoDragDrop() call
 enum wxDragResult
 {
@@ -80,8 +91,10 @@ public:
 
     // start drag action, see enum wxDragResult for return value description
     //
-    // if bAllowMove is TRUE, data can be moved, if not - only copied
-    virtual wxDragResult DoDragDrop(bool bAllowMove = FALSE) = 0;
+    // if flags contains wxDrag_AllowMove, moving (and only copying) data is
+    // allowed, if it contains wxDrag_DefaultMove (which includes the previous
+    // flag), it is even the default operation
+    virtual wxDragResult DoDragDrop(int flags = wxDrag_CopyOnly) = 0;
 
     // override to give feedback depending on the current operation result
     // "effect" and return TRUE if you did something, FALSE to let the library
@@ -99,10 +112,13 @@ protected:
             return m_cursorStop;
     }
 
+    // the data we're dragging
     wxDataObject *m_data;
 
     // the cursors to use for feedback
-    wxCursor      m_cursorCopy, m_cursorMove, m_cursorStop;
+    wxCursor m_cursorCopy,
+             m_cursorMove,
+             m_cursorStop;
 };
 
 // ----------------------------------------------------------------------------
index 52199517b47c017dae7450e935b909d1174f9862..a733897cb932c05563386ce189c77e21ba83cdea 100644 (file)
@@ -71,7 +71,7 @@ public:
     GtkWidget          *m_dragWidget;
     GtkSelectionData   *m_dragData;
     guint               m_dragTime;
-    bool                m_firstMotion;     /* gdk has no "gdk_drag_enter" event */
+    bool                m_firstMotion;     // gdk has no "gdk_drag_enter" event
 
     void SetDragContext( GdkDragContext *dc ) { m_dragContext = dc; }
     void SetDragWidget( GtkWidget *w ) { m_dragWidget = w; }
@@ -86,25 +86,25 @@ public:
 class wxDropSource: public wxDropSourceBase
 {
 public:
-    /* constructor. set data later with SetData() */
+    // constructor. set data later with SetData()
     wxDropSource( wxWindow *win = (wxWindow *)NULL,
                   const wxIcon &copy = wxNullIcon,
                   const wxIcon &move = wxNullIcon,
                   const wxIcon &none = wxNullIcon);
 
-    /* constructor for setting one data object */
+    // constructor for setting one data object
     wxDropSource( wxDataObject& data,
                   wxWindow *win,
                   const wxIcon &copy = wxNullIcon,
                   const wxIcon &move = wxNullIcon,
                   const wxIcon &none = wxNullIcon);
 
-    ~wxDropSource();
+    virtual ~wxDropSource();
 
-    /* start drag action */
-    virtual wxDragResult DoDragDrop( bool bAllowMove = FALSE );
+    // start drag action
+    virtual wxDragResult DoDragDrop(int flags = wxDrag_CopyOnly);
 
-    /* GTK implementation */
+    // GTK implementation
     void RegisterWindow();
     void UnregisterWindow();
 
@@ -129,10 +129,7 @@ private:
                   const wxIcon& none);
 };
 
-#endif
-
-   // wxUSE_DRAG_AND_DROP
+#endif // wxUSE_DRAG_AND_DROP
 
-#endif
-       //__GTKDNDH__
+#endif //__GTKDNDH__
 
index 52199517b47c017dae7450e935b909d1174f9862..a733897cb932c05563386ce189c77e21ba83cdea 100644 (file)
@@ -71,7 +71,7 @@ public:
     GtkWidget          *m_dragWidget;
     GtkSelectionData   *m_dragData;
     guint               m_dragTime;
-    bool                m_firstMotion;     /* gdk has no "gdk_drag_enter" event */
+    bool                m_firstMotion;     // gdk has no "gdk_drag_enter" event
 
     void SetDragContext( GdkDragContext *dc ) { m_dragContext = dc; }
     void SetDragWidget( GtkWidget *w ) { m_dragWidget = w; }
@@ -86,25 +86,25 @@ public:
 class wxDropSource: public wxDropSourceBase
 {
 public:
-    /* constructor. set data later with SetData() */
+    // constructor. set data later with SetData()
     wxDropSource( wxWindow *win = (wxWindow *)NULL,
                   const wxIcon &copy = wxNullIcon,
                   const wxIcon &move = wxNullIcon,
                   const wxIcon &none = wxNullIcon);
 
-    /* constructor for setting one data object */
+    // constructor for setting one data object
     wxDropSource( wxDataObject& data,
                   wxWindow *win,
                   const wxIcon &copy = wxNullIcon,
                   const wxIcon &move = wxNullIcon,
                   const wxIcon &none = wxNullIcon);
 
-    ~wxDropSource();
+    virtual ~wxDropSource();
 
-    /* start drag action */
-    virtual wxDragResult DoDragDrop( bool bAllowMove = FALSE );
+    // start drag action
+    virtual wxDragResult DoDragDrop(int flags = wxDrag_CopyOnly);
 
-    /* GTK implementation */
+    // GTK implementation
     void RegisterWindow();
     void UnregisterWindow();
 
@@ -129,10 +129,7 @@ private:
                   const wxIcon& none);
 };
 
-#endif
-
-   // wxUSE_DRAG_AND_DROP
+#endif // wxUSE_DRAG_AND_DROP
 
-#endif
-       //__GTKDNDH__
+#endif //__GTKDNDH__
 
index ee95777c01ce6bee929f7258e7a710504a6a6d2b..252d2376147aa42be7de5dd39051b23172a9ead2 100644 (file)
@@ -91,7 +91,7 @@ public:
     ~wxDropSource();
 
     /* start drag action */
-    virtual wxDragResult DoDragDrop( bool bAllowMove = FALSE );
+    virtual wxDragResult DoDragDrop(int flags = wxDrag_CopyOnly);
     
     wxWindow*     GetWindow() { return m_window ; }
     void SetCurrentDrag( void* drag ) { m_currentDrag = drag ; }
index b3944af30cbfd51f5d627465c333fdaf0a3b80cc..fa392bd9d8bdf921522fb47c281aff9e62370aa5 100644 (file)
@@ -151,7 +151,7 @@ public:
     ~wxDropSource(void);
     
     void SetData( wxDataObject &data  );
-    wxDragResult DoDragDrop( bool bAllowMove = FALSE );
+    wxDragResult DoDragDrop(int flags = wxDrag_CopyOnly);
     
     virtual bool GiveFeedback( wxDragResult WXUNUSED(effect), bool WXUNUSED(bScrolling) ) { return TRUE; };
     
index 4765f2e6df9f49e07cdd15c1a77fc3efaae0d209..7e719f843e627cac9533216926a137b5a1281f70 100644 (file)
@@ -64,7 +64,7 @@ public:
 
     // do it (call this in response to a mouse button press, for example)
     // params: if bAllowMove is false, data can be only copied
-    virtual wxDragResult DoDragDrop(bool bAllowMove = FALSE);
+    virtual wxDragResult DoDragDrop(int flags = wxDrag_CopyOnly);
 
     // overridable: you may give some custom UI feedback during d&d operation
     // in this function (it's called on each mouse move, so it shouldn't be
index a92c744745095a20cae5b856ba21696a78b1670b..48976e760f9adbc4dceb844306edc835568edb20 100644 (file)
@@ -40,7 +40,7 @@ public:
     virtual ~wxDropSource();
 
     /* start drag action */
-    virtual wxDragResult DoDragDrop(bool bAllowMove = FALSE);
+    virtual wxDragResult DoDragDrop(int flags = wxDrag_CopyOnly);
 
 protected:
     void Init(void);
index b3944af30cbfd51f5d627465c333fdaf0a3b80cc..fa392bd9d8bdf921522fb47c281aff9e62370aa5 100644 (file)
@@ -151,7 +151,7 @@ public:
     ~wxDropSource(void);
     
     void SetData( wxDataObject &data  );
-    wxDragResult DoDragDrop( bool bAllowMove = FALSE );
+    wxDragResult DoDragDrop(int flags = wxDrag_CopyOnly);
     
     virtual bool GiveFeedback( wxDragResult WXUNUSED(effect), bool WXUNUSED(bScrolling) ) { return TRUE; };
     
index 91c6cc0d2ed59f636778aa3630dc7e7b0fd03375..892a621cc17f8fda1a7660d07cca1daf85250d73 100644 (file)
@@ -74,16 +74,6 @@ public:
 
     virtual bool OnDropText(wxCoord x, wxCoord y, const wxString& text);
 
-    // uncomment this if you want to always force Move to be the default
-    // action, even under wxGTK where it is normally Copy
-#if 0
-    wxDragResult OnDragOver(wxCoord x, wxCoord y, wxDragResult def)
-    {
-        wxDragResult res = wxTextDropTarget::OnDragOver(x, y, def);
-        return res == wxDragNone ? wxDragNone : wxDragMove;
-    }
-#endif // 0
-
 private:
     wxListBox *m_pOwner;
 };
@@ -231,13 +221,15 @@ class DnDFrame : public wxFrame
 {
 public:
     DnDFrame(wxFrame *frame, char *title, int x, int y, int w, int h);
-    ~DnDFrame();
+    virtual ~DnDFrame();
 
     void OnPaint(wxPaintEvent& event);
     void OnSize(wxSizeEvent& event);
-    void OnQuit (wxCommandEvent& event);
+    void OnQuit(wxCommandEvent& event);
     void OnAbout(wxCommandEvent& event);
-    void OnDrag (wxCommandEvent& event);
+    void OnDrag(wxCommandEvent& event);
+    void OnDragMoveByDefault(wxCommandEvent& event);
+    void OnDragMoveAllow(wxCommandEvent& event);
     void OnNewFrame(wxCommandEvent& event);
     void OnHelp (wxCommandEvent& event);
     void OnLogClear(wxCommandEvent& event);
@@ -257,12 +249,15 @@ public:
     void OnLeftDown(wxMouseEvent& event);
     void OnRightDown(wxMouseEvent& event);
 
+    void OnUpdateUIMoveByDefault(wxUpdateUIEvent& event);
+
     void OnUpdateUIPasteText(wxUpdateUIEvent& event);
     void OnUpdateUIPasteBitmap(wxUpdateUIEvent& event);
 
     DECLARE_EVENT_TABLE()
 
 private:
+    // GUI controls
     wxListBox  *m_ctrlFile,
                *m_ctrlText;
     wxTextCtrl *m_ctrlLog;
@@ -270,6 +265,13 @@ private:
     wxLog *m_pLog,
           *m_pLogPrev;
 
+    // move the text by default (or copy)?
+    bool m_moveByDefault;
+
+    // allow moving the text at all?
+    bool m_moveAllow;
+
+    // the text we drag
     wxString  m_strText;
 };
 
@@ -786,6 +788,8 @@ enum
 {
     Menu_Quit = 1,
     Menu_Drag,
+    Menu_DragMoveDef,
+    Menu_DragMoveAllow,
     Menu_NewFrame,
     Menu_About = 101,
     Menu_Help,
@@ -808,6 +812,8 @@ BEGIN_EVENT_TABLE(DnDFrame, wxFrame)
     EVT_MENU(Menu_Quit,       DnDFrame::OnQuit)
     EVT_MENU(Menu_About,      DnDFrame::OnAbout)
     EVT_MENU(Menu_Drag,       DnDFrame::OnDrag)
+    EVT_MENU(Menu_DragMoveDef,  DnDFrame::OnDragMoveByDefault)
+    EVT_MENU(Menu_DragMoveAllow,DnDFrame::OnDragMoveAllow)
     EVT_MENU(Menu_NewFrame,   DnDFrame::OnNewFrame)
     EVT_MENU(Menu_Help,       DnDFrame::OnHelp)
     EVT_MENU(Menu_Clear,      DnDFrame::OnLogClear)
@@ -820,6 +826,8 @@ BEGIN_EVENT_TABLE(DnDFrame, wxFrame)
 #endif // USE_METAFILES
     EVT_MENU(Menu_CopyFiles,  DnDFrame::OnCopyFiles)
 
+    EVT_UPDATE_UI(Menu_DragMoveDef, DnDFrame::OnUpdateUIMoveByDefault)
+
     EVT_UPDATE_UI(Menu_Paste,       DnDFrame::OnUpdateUIPasteText)
     EVT_UPDATE_UI(Menu_PasteBitmap, DnDFrame::OnUpdateUIPasteBitmap)
 
@@ -928,6 +936,8 @@ DnDFrame::DnDFrame(wxFrame *frame, char *title, int x, int y, int w, int h)
     // construct menu
     wxMenu *file_menu = new wxMenu;
     file_menu->Append(Menu_Drag, "&Test drag...");
+    file_menu->AppendCheckItem(Menu_DragMoveDef, "&Move by default");
+    file_menu->AppendCheckItem(Menu_DragMoveAllow, "&Allow moving");
     file_menu->AppendSeparator();
     file_menu->Append(Menu_NewFrame, "&New frame\tCtrl-N");
     file_menu->AppendSeparator();
@@ -1013,6 +1023,11 @@ DnDFrame::DnDFrame(wxFrame *frame, char *title, int x, int y, int w, int h)
     m_ctrlLog->SetConstraints(c);
 
     SetAutoLayout(TRUE);
+
+    // copy data by default but allow moving it as well
+    m_moveByDefault = FALSE;
+    m_moveAllow = TRUE;
+    menu_bar->Check(Menu_DragMoveAllow, TRUE);
 }
 
 void DnDFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
@@ -1039,6 +1054,12 @@ void DnDFrame::OnPaint(wxPaintEvent& WXUNUSED(event))
     dc.DrawText( "Drag text from here!", 100, h-50 );
 }
 
+void DnDFrame::OnUpdateUIMoveByDefault(wxUpdateUIEvent& event)
+{
+    // only can move by default if moving is allowed at all
+    event.Enable(m_moveAllow);
+}
+
 void DnDFrame::OnUpdateUIPasteText(wxUpdateUIEvent& event)
 {
 #ifdef __WXDEBUG__
@@ -1082,6 +1103,16 @@ void DnDFrame::OnDrag(wxCommandEvent& WXUNUSED(event))
     m_strText = strText;
 }
 
+void DnDFrame::OnDragMoveByDefault(wxCommandEvent& event)
+{
+    m_moveByDefault = event.IsChecked();
+}
+
+void DnDFrame::OnDragMoveAllow(wxCommandEvent& event)
+{
+    m_moveAllow = event.IsChecked();
+}
+
 void DnDFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
 {
     wxMessageBox("Drag-&-Drop Demo\n"
@@ -1143,9 +1174,14 @@ void DnDFrame::OnLeftDown(wxMouseEvent &WXUNUSED(event) )
                             wxDROP_ICON(dnd_move),
                             wxDROP_ICON(dnd_none));
 
-        const char *pc;
+        int flags = 0;
+        if ( m_moveByDefault )
+            flags |= wxDrag_DefaultMove;
+        else if ( m_moveAllow )
+            flags |= wxDrag_AllowMove;
 
-        switch ( source.DoDragDrop(TRUE) )
+        const char *pc;
+        switch ( source.DoDragDrop(flags) )
         {
             case wxDragError:   pc = "Error!";    break;
             case wxDragNone:    pc = "Nothing";   break;
index 7c1834bf873532c38122e53152db4876e2f2a01c..ca8a96f4b620c6c7ef9ff146ab1f9f721b99cfa4 100644 (file)
@@ -48,6 +48,9 @@ extern bool g_isIdle;
 
 extern bool g_blockEventsOnDrag;
 
+// the flags used for the last DoDragDrop()
+static long gs_flagsForDrag = 0;
+
 // the trace mask we use with wxLogTrace() - call
 // wxLog::AddTraceMask(TRACE_DND) to enable the trace messages from here
 // (there are quite a few of them, so don't enable this by default)
@@ -102,6 +105,30 @@ static const char * page_xpm[] = {
 "    .........................   "};
 
 
+// ============================================================================
+// private functions
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// convert between GTK+ and wxWindows DND constants
+// ----------------------------------------------------------------------------
+
+static wxDragResult ConvertFromGTK(long action)
+{
+    switch ( action )
+    {
+        case GDK_ACTION_COPY:
+            return wxDragCopy;
+
+        case GDK_ACTION_LINK:
+            return wxDragLink;
+
+        case GDK_ACTION_MOVE:
+            return wxDragMove;
+    }
+
+    return wxDragNone;
+}
 
 // ----------------------------------------------------------------------------
 // "drag_leave"
@@ -150,13 +177,28 @@ static gboolean target_drag_motion( GtkWidget *WXUNUSED(widget),
        this is only valid for the duration of this call */
     drop_target->SetDragContext( context );
 
+    // GTK+ always supposes that we want to copy the data by default while we
+    // might want to move it, so examine not only suggested_action - which is
+    // only good if we don't have our own preferences - but also the actions
+    // field
     wxDragResult result;
-    if ( context->suggested_action == GDK_ACTION_COPY )
-        result = wxDragCopy;
-    else if ( context->suggested_action == GDK_ACTION_LINK )
-        result = wxDragLink;
-    else
+    if ( (gs_flagsForDrag & wxDrag_DefaultMove) == wxDrag_DefaultMove &&
+            (context->actions & GDK_ACTION_MOVE ) )
+    {
+        // move is requested by the program and allowed by GTK+ - do it, even
+        // though suggested_action may be currently wxDragCopy
         result = wxDragMove;
+    }
+    else // use whatever GTK+ says we should
+    {
+        result = ConvertFromGTK(context->suggested_action);
+
+        if ( (result == wxDragMove) && !(gs_flagsForDrag & wxDrag_AllowMove) )
+        {
+            // we're requested to move but we can't
+            result = wxDragCopy;
+        }
+    }
 
     if (drop_target->m_firstMotion)
     {
@@ -322,13 +364,7 @@ static void target_drag_data_received( GtkWidget *WXUNUSED(widget),
        this is only valid for the duration of this call */
     drop_target->SetDragData( data );
 
-    wxDragResult result;
-    if ( context->suggested_action == GDK_ACTION_COPY )
-        result = wxDragCopy;
-    else if ( context->suggested_action == GDK_ACTION_LINK )
-        result = wxDragLink;
-    else
-        result = wxDragMove;
+    wxDragResult result = ConvertFromGTK(context->suggested_action);
 
     if ( wxIsDragResultOk( drop_target->OnData( x, y, result ) ) )
     {
@@ -619,12 +655,7 @@ gtk_dnd_window_configure_callback( GtkWidget *WXUNUSED(widget), GdkEventConfigur
     if (g_isIdle)
         wxapp_install_idle_handler();
 
-    wxDragResult action = wxDragNone;
-    if (source->m_dragContext->action == GDK_ACTION_COPY) action = wxDragCopy;
-    if (source->m_dragContext->action == GDK_ACTION_LINK) action = wxDragLink;
-    if (source->m_dragContext->action == GDK_ACTION_MOVE) action = wxDragMove;
-
-    source->GiveFeedback( action );
+    source->GiveFeedback( ConvertFromGTK(source->m_dragContext->action) );
 
     return 0;
 }
@@ -743,19 +774,14 @@ void wxDropSource::PrepareIcon( int action, GdkDragContext *context )
     gtk_drag_set_icon_widget( context, m_iconWindow, 0, 0 );
 }
 
-wxDragResult wxDropSource::DoDragDrop( bool allowMove )
+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;
+    wxCHECK_MSG( m_data && m_data->GetFormatCount(), wxDragNone,
+                 wxT("Drop source: no data") );
 
     // still in drag
     if (g_blockEventsOnDrag)
-        return (wxDragResult) wxDragNone;
+        return wxDragNone;
 
     // disabled for now
     g_blockEventsOnDrag = TRUE;
@@ -768,7 +794,8 @@ wxDragResult wxDropSource::DoDragDrop( bool allowMove )
 
     wxDataFormat *array = new wxDataFormat[ m_data->GetFormatCount() ];
     m_data->GetAllFormats( array );
-    for (size_t i = 0; i < m_data->GetFormatCount(); i++)
+    size_t count = m_data->GetFormatCount();
+    for (size_t i = 0; i < count; i++)
     {
         GdkAtom atom = array[i];
         wxLogTrace(TRACE_DND, wxT("Drop source: Supported atom %s"), gdk_atom_name( atom ));
@@ -801,8 +828,14 @@ wxDragResult wxDropSource::DoDragDrop( bool allowMove )
     if (button_number)
     {
         int action = GDK_ACTION_COPY;
-        if ( allowMove )
+        if ( flags & wxDrag_AllowMove )
             action |= GDK_ACTION_MOVE;
+
+        // VZ: as we already use g_blockEventsOnDrag it shouldn't be that bad
+        //     to use a global to pass the flags to the drop target but I'd
+        //     surely prefer a better way to do it
+        gs_flagsForDrag = flags;
+
         GdkDragContext *context = gtk_drag_begin( m_widget,
                 target_list,
                 (GdkDragAction)action,
@@ -813,14 +846,12 @@ wxDragResult wxDropSource::DoDragDrop( bool allowMove )
 
         PrepareIcon( action, context );
 
-        while (m_waiting) gtk_main_iteration();
+        while (m_waiting)
+            gtk_main_iteration();
 
-        if (context->action == GDK_ACTION_COPY)
-            m_retValue = wxDragCopy;
-        if (context->action == GDK_ACTION_LINK)
-            m_retValue = wxDragLink;
-        if (context->action == GDK_ACTION_MOVE)
-            m_retValue = wxDragMove;
+        m_retValue = ConvertFromGTK(context->action);
+        if ( m_retValue == wxDragNone )
+            m_retValue = wxDragCancel;
     }
 
 #if wxUSE_THREADS
index 7c1834bf873532c38122e53152db4876e2f2a01c..ca8a96f4b620c6c7ef9ff146ab1f9f721b99cfa4 100644 (file)
@@ -48,6 +48,9 @@ extern bool g_isIdle;
 
 extern bool g_blockEventsOnDrag;
 
+// the flags used for the last DoDragDrop()
+static long gs_flagsForDrag = 0;
+
 // the trace mask we use with wxLogTrace() - call
 // wxLog::AddTraceMask(TRACE_DND) to enable the trace messages from here
 // (there are quite a few of them, so don't enable this by default)
@@ -102,6 +105,30 @@ static const char * page_xpm[] = {
 "    .........................   "};
 
 
+// ============================================================================
+// private functions
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// convert between GTK+ and wxWindows DND constants
+// ----------------------------------------------------------------------------
+
+static wxDragResult ConvertFromGTK(long action)
+{
+    switch ( action )
+    {
+        case GDK_ACTION_COPY:
+            return wxDragCopy;
+
+        case GDK_ACTION_LINK:
+            return wxDragLink;
+
+        case GDK_ACTION_MOVE:
+            return wxDragMove;
+    }
+
+    return wxDragNone;
+}
 
 // ----------------------------------------------------------------------------
 // "drag_leave"
@@ -150,13 +177,28 @@ static gboolean target_drag_motion( GtkWidget *WXUNUSED(widget),
        this is only valid for the duration of this call */
     drop_target->SetDragContext( context );
 
+    // GTK+ always supposes that we want to copy the data by default while we
+    // might want to move it, so examine not only suggested_action - which is
+    // only good if we don't have our own preferences - but also the actions
+    // field
     wxDragResult result;
-    if ( context->suggested_action == GDK_ACTION_COPY )
-        result = wxDragCopy;
-    else if ( context->suggested_action == GDK_ACTION_LINK )
-        result = wxDragLink;
-    else
+    if ( (gs_flagsForDrag & wxDrag_DefaultMove) == wxDrag_DefaultMove &&
+            (context->actions & GDK_ACTION_MOVE ) )
+    {
+        // move is requested by the program and allowed by GTK+ - do it, even
+        // though suggested_action may be currently wxDragCopy
         result = wxDragMove;
+    }
+    else // use whatever GTK+ says we should
+    {
+        result = ConvertFromGTK(context->suggested_action);
+
+        if ( (result == wxDragMove) && !(gs_flagsForDrag & wxDrag_AllowMove) )
+        {
+            // we're requested to move but we can't
+            result = wxDragCopy;
+        }
+    }
 
     if (drop_target->m_firstMotion)
     {
@@ -322,13 +364,7 @@ static void target_drag_data_received( GtkWidget *WXUNUSED(widget),
        this is only valid for the duration of this call */
     drop_target->SetDragData( data );
 
-    wxDragResult result;
-    if ( context->suggested_action == GDK_ACTION_COPY )
-        result = wxDragCopy;
-    else if ( context->suggested_action == GDK_ACTION_LINK )
-        result = wxDragLink;
-    else
-        result = wxDragMove;
+    wxDragResult result = ConvertFromGTK(context->suggested_action);
 
     if ( wxIsDragResultOk( drop_target->OnData( x, y, result ) ) )
     {
@@ -619,12 +655,7 @@ gtk_dnd_window_configure_callback( GtkWidget *WXUNUSED(widget), GdkEventConfigur
     if (g_isIdle)
         wxapp_install_idle_handler();
 
-    wxDragResult action = wxDragNone;
-    if (source->m_dragContext->action == GDK_ACTION_COPY) action = wxDragCopy;
-    if (source->m_dragContext->action == GDK_ACTION_LINK) action = wxDragLink;
-    if (source->m_dragContext->action == GDK_ACTION_MOVE) action = wxDragMove;
-
-    source->GiveFeedback( action );
+    source->GiveFeedback( ConvertFromGTK(source->m_dragContext->action) );
 
     return 0;
 }
@@ -743,19 +774,14 @@ void wxDropSource::PrepareIcon( int action, GdkDragContext *context )
     gtk_drag_set_icon_widget( context, m_iconWindow, 0, 0 );
 }
 
-wxDragResult wxDropSource::DoDragDrop( bool allowMove )
+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;
+    wxCHECK_MSG( m_data && m_data->GetFormatCount(), wxDragNone,
+                 wxT("Drop source: no data") );
 
     // still in drag
     if (g_blockEventsOnDrag)
-        return (wxDragResult) wxDragNone;
+        return wxDragNone;
 
     // disabled for now
     g_blockEventsOnDrag = TRUE;
@@ -768,7 +794,8 @@ wxDragResult wxDropSource::DoDragDrop( bool allowMove )
 
     wxDataFormat *array = new wxDataFormat[ m_data->GetFormatCount() ];
     m_data->GetAllFormats( array );
-    for (size_t i = 0; i < m_data->GetFormatCount(); i++)
+    size_t count = m_data->GetFormatCount();
+    for (size_t i = 0; i < count; i++)
     {
         GdkAtom atom = array[i];
         wxLogTrace(TRACE_DND, wxT("Drop source: Supported atom %s"), gdk_atom_name( atom ));
@@ -801,8 +828,14 @@ wxDragResult wxDropSource::DoDragDrop( bool allowMove )
     if (button_number)
     {
         int action = GDK_ACTION_COPY;
-        if ( allowMove )
+        if ( flags & wxDrag_AllowMove )
             action |= GDK_ACTION_MOVE;
+
+        // VZ: as we already use g_blockEventsOnDrag it shouldn't be that bad
+        //     to use a global to pass the flags to the drop target but I'd
+        //     surely prefer a better way to do it
+        gs_flagsForDrag = flags;
+
         GdkDragContext *context = gtk_drag_begin( m_widget,
                 target_list,
                 (GdkDragAction)action,
@@ -813,14 +846,12 @@ wxDragResult wxDropSource::DoDragDrop( bool allowMove )
 
         PrepareIcon( action, context );
 
-        while (m_waiting) gtk_main_iteration();
+        while (m_waiting)
+            gtk_main_iteration();
 
-        if (context->action == GDK_ACTION_COPY)
-            m_retValue = wxDragCopy;
-        if (context->action == GDK_ACTION_LINK)
-            m_retValue = wxDragLink;
-        if (context->action == GDK_ACTION_MOVE)
-            m_retValue = wxDragMove;
+        m_retValue = ConvertFromGTK(context->action);
+        if ( m_retValue == wxDragNone )
+            m_retValue = wxDragCancel;
     }
 
 #if wxUSE_THREADS
index 7ab73a19d11fa3b70ab19ea54994f5689437b44c..33ad69d413848af188e4a2af7eda7b3915f47bbf 100644 (file)
@@ -259,7 +259,7 @@ wxDropSource::~wxDropSource()
 }
 
 
-wxDragResult wxDropSource::DoDragDrop( bool allowMove )
+wxDragResult wxDropSource::DoDragDrop(int WXUNUSED(flags))
 {
     wxASSERT_MSG( m_data, wxT("Drop source: no data") );
 
index 7ab73a19d11fa3b70ab19ea54994f5689437b44c..33ad69d413848af188e4a2af7eda7b3915f47bbf 100644 (file)
@@ -259,7 +259,7 @@ wxDropSource::~wxDropSource()
 }
 
 
-wxDragResult wxDropSource::DoDragDrop( bool allowMove )
+wxDragResult wxDropSource::DoDragDrop(int WXUNUSED(flags))
 {
     wxASSERT_MSG( m_data, wxT("Drop source: no data") );
 
index e9e57e42f8891de0ccd5fdfa8250be45338c8cc2..f4a9cefec71195a1ed465d0f5002f14fd96d0255 100644 (file)
@@ -164,7 +164,7 @@ wxDropSource::~wxDropSource(void)
 //  if (m_data) delete m_data;
 }
    
-wxDragResult wxDropSource::DoDragDrop( bool WXUNUSED(bAllowMove) )
+wxDragResult wxDropSource::DoDragDrop( int WXUNUSED(flags) )
 {
   //  wxASSERT_MSG( m_data, "wxDragSource: no data" );
 
index 9aa2b238c5357d9e5957b50453ff7e704b5edff9..6aae42c5d549cb91c1da54caf4257a5131128b64 100644 (file)
@@ -187,17 +187,18 @@ wxDropSource::~wxDropSource()
 // Name    : DoDragDrop
 // Purpose : start drag and drop operation
 // Returns : wxDragResult - the code of performed operation
-// Params  : [in] bool bAllowMove: if false, only copy is allowed
+// Params  : [in] int flags: specifies if moving is allowe (or only copying)
 // Notes   : you must call SetData() before if you had used def ctor
-wxDragResult wxDropSource::DoDragDrop(bool bAllowMove)
+wxDragResult wxDropSource::DoDragDrop(int flags)
 {
   wxCHECK_MSG( m_data != NULL, wxDragNone, wxT("No data in wxDropSource!") );
 
   DWORD dwEffect;
   HRESULT hr = ::DoDragDrop(m_data->GetInterface(),
                             m_pIDropSource,
-                            bAllowMove ? DROPEFFECT_COPY | DROPEFFECT_MOVE
-                                       : DROPEFFECT_COPY,
+                            (flags & wxDrag_AllowMove)
+                                ? DROPEFFECT_COPY | DROPEFFECT_MOVE
+                                : DROPEFFECT_COPY,
                             &dwEffect);
 
   if ( hr == DRAGDROP_S_CANCEL ) {
@@ -209,11 +210,8 @@ wxDragResult wxDropSource::DoDragDrop(bool bAllowMove)
     }
     else if ( dwEffect & DROPEFFECT_MOVE ) {
       // consistency check: normally, we shouldn't get "move" at all
-      // here if !bAllowMove, but in practice it does happen quite often
-      if ( bAllowMove )
-        return wxDragMove;
-      else
-        return wxDragCopy;
+      // here if we don't allow it, but in practice it does happen quite often
+      return (flags & wxDrag_AllowMove) ? wxDragMove : wxDragCopy;
     }
     else {
       // not copy or move
index 70d916d6528af2565d4fcb688aec4e35a6d76a2a..463d738fa9a1851a86d400468649544e02a16968 100644 (file)
@@ -124,7 +124,7 @@ wxDropSource::~wxDropSource()
 };
 
 wxDragResult wxDropSource::DoDragDrop(
-  bool                              WXUNUSED(bAllowMove)
+  int                              WXUNUSED(flags)
 )
 {
     // TODO
index e9e57e42f8891de0ccd5fdfa8250be45338c8cc2..f4a9cefec71195a1ed465d0f5002f14fd96d0255 100644 (file)
@@ -164,7 +164,7 @@ wxDropSource::~wxDropSource(void)
 //  if (m_data) delete m_data;
 }
    
-wxDragResult wxDropSource::DoDragDrop( bool WXUNUSED(bAllowMove) )
+wxDragResult wxDropSource::DoDragDrop( int WXUNUSED(flags) )
 {
   //  wxASSERT_MSG( m_data, "wxDragSource: no data" );