From 2245b2b2c3339ecf023e5880caa803610a5d1907 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 28 Apr 2002 14:30:54 +0000 Subject: [PATCH] changed DoDragDrop(bool) into DoDragDrop(int) and added support for wxDrag_DefaultMove flag git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@15297 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/latex/wx/dropsrc.tex | 18 +++++- include/wx/dnd.h | 22 +++++++- include/wx/gtk/dnd.h | 21 +++---- include/wx/gtk1/dnd.h | 21 +++---- include/wx/mac/dnd.h | 2 +- include/wx/motif/dnd.h | 2 +- include/wx/msw/ole/dropsrc.h | 2 +- include/wx/os2/dnd.h | 2 +- include/wx/x11/dnd.h | 2 +- samples/dnd/dnd.cpp | 66 +++++++++++++++++----- src/gtk/dnd.cpp | 103 +++++++++++++++++++++++------------ src/gtk1/dnd.cpp | 103 +++++++++++++++++++++++------------ src/mac/carbon/dnd.cpp | 2 +- src/mac/dnd.cpp | 2 +- src/motif/dnd.cpp | 2 +- src/msw/ole/dropsrc.cpp | 16 +++--- src/os2/dnd.cpp | 2 +- src/x11/dnd.cpp | 2 +- 18 files changed, 254 insertions(+), 136 deletions(-) diff --git a/docs/latex/wx/dropsrc.tex b/docs/latex/wx/dropsrc.tex index 9b306331ee..6223ea5e88 100644 --- a/docs/latex/wx/dropsrc.tex +++ b/docs/latex/wx/dropsrc.tex @@ -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} diff --git a/include/wx/dnd.h b/include/wx/dnd.h index 61f7625876..7ce567f726 100644 --- a/include/wx/dnd.h +++ b/include/wx/dnd.h @@ -27,6 +27,17 @@ // 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; }; // ---------------------------------------------------------------------------- diff --git a/include/wx/gtk/dnd.h b/include/wx/gtk/dnd.h index 52199517b4..a733897cb9 100644 --- a/include/wx/gtk/dnd.h +++ b/include/wx/gtk/dnd.h @@ -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 © = 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 © = 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__ diff --git a/include/wx/gtk1/dnd.h b/include/wx/gtk1/dnd.h index 52199517b4..a733897cb9 100644 --- a/include/wx/gtk1/dnd.h +++ b/include/wx/gtk1/dnd.h @@ -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 © = 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 © = 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__ diff --git a/include/wx/mac/dnd.h b/include/wx/mac/dnd.h index ee95777c01..252d237614 100644 --- a/include/wx/mac/dnd.h +++ b/include/wx/mac/dnd.h @@ -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 ; } diff --git a/include/wx/motif/dnd.h b/include/wx/motif/dnd.h index b3944af30c..fa392bd9d8 100644 --- a/include/wx/motif/dnd.h +++ b/include/wx/motif/dnd.h @@ -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; }; diff --git a/include/wx/msw/ole/dropsrc.h b/include/wx/msw/ole/dropsrc.h index 4765f2e6df..7e719f843e 100644 --- a/include/wx/msw/ole/dropsrc.h +++ b/include/wx/msw/ole/dropsrc.h @@ -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 diff --git a/include/wx/os2/dnd.h b/include/wx/os2/dnd.h index a92c744745..48976e760f 100644 --- a/include/wx/os2/dnd.h +++ b/include/wx/os2/dnd.h @@ -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); diff --git a/include/wx/x11/dnd.h b/include/wx/x11/dnd.h index b3944af30c..fa392bd9d8 100644 --- a/include/wx/x11/dnd.h +++ b/include/wx/x11/dnd.h @@ -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; }; diff --git a/samples/dnd/dnd.cpp b/samples/dnd/dnd.cpp index 91c6cc0d2e..892a621cc1 100644 --- a/samples/dnd/dnd.cpp +++ b/samples/dnd/dnd.cpp @@ -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; diff --git a/src/gtk/dnd.cpp b/src/gtk/dnd.cpp index 7c1834bf87..ca8a96f4b6 100644 --- a/src/gtk/dnd.cpp +++ b/src/gtk/dnd.cpp @@ -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 diff --git a/src/gtk1/dnd.cpp b/src/gtk1/dnd.cpp index 7c1834bf87..ca8a96f4b6 100644 --- a/src/gtk1/dnd.cpp +++ b/src/gtk1/dnd.cpp @@ -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 diff --git a/src/mac/carbon/dnd.cpp b/src/mac/carbon/dnd.cpp index 7ab73a19d1..33ad69d413 100644 --- a/src/mac/carbon/dnd.cpp +++ b/src/mac/carbon/dnd.cpp @@ -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") ); diff --git a/src/mac/dnd.cpp b/src/mac/dnd.cpp index 7ab73a19d1..33ad69d413 100644 --- a/src/mac/dnd.cpp +++ b/src/mac/dnd.cpp @@ -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") ); diff --git a/src/motif/dnd.cpp b/src/motif/dnd.cpp index e9e57e42f8..f4a9cefec7 100644 --- a/src/motif/dnd.cpp +++ b/src/motif/dnd.cpp @@ -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" ); diff --git a/src/msw/ole/dropsrc.cpp b/src/msw/ole/dropsrc.cpp index 9aa2b238c5..6aae42c5d5 100644 --- a/src/msw/ole/dropsrc.cpp +++ b/src/msw/ole/dropsrc.cpp @@ -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 diff --git a/src/os2/dnd.cpp b/src/os2/dnd.cpp index 70d916d652..463d738fa9 100644 --- a/src/os2/dnd.cpp +++ b/src/os2/dnd.cpp @@ -124,7 +124,7 @@ wxDropSource::~wxDropSource() }; wxDragResult wxDropSource::DoDragDrop( - bool WXUNUSED(bAllowMove) + int WXUNUSED(flags) ) { // TODO diff --git a/src/x11/dnd.cpp b/src/x11/dnd.cpp index e9e57e42f8..f4a9cefec7 100644 --- a/src/x11/dnd.cpp +++ b/src/x11/dnd.cpp @@ -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" ); -- 2.45.2