diff --git a/include/wx/dataobj.h b/include/wx/dataobj.h index 1785016500..b7680b5c95 100644 --- a/include/wx/dataobj.h +++ b/include/wx/dataobj.h @@ -322,7 +322,7 @@ private: // ---------------------------------------------------------------------------- #if wxUSE_UNICODE - #if defined(__WXGTK20__) || defined(__WXX11__) + #if defined(__WXGTK20__) || defined(__WXX11__) || defined(__WXQT__) #define wxNEEDS_UTF8_FOR_TEXT_DATAOBJ #elif defined(__WXMAC__) #define wxNEEDS_UTF16_FOR_TEXT_DATAOBJ diff --git a/include/wx/qt/dataform.h b/include/wx/qt/dataform.h index 4447e8a681..55932a5815 100644 --- a/include/wx/qt/dataform.h +++ b/include/wx/qt/dataform.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: wx/qt/toolbar.h +// Name: wx/qt/dataform.h // Author: Sean D'Epagnier // Copyright: (c) Sean D'Epagnier 2014 // Licence: wxWindows licence @@ -8,34 +8,34 @@ #ifndef _WX_QT_DATAFORM_H_ #define _WX_QT_DATAFORM_H_ -class QString; - class WXDLLIMPEXP_CORE wxDataFormat { public: - wxDataFormat(); - wxDataFormat( wxDataFormatId formatId ); + wxDataFormat(wxDataFormatId formatId = wxDF_INVALID); wxDataFormat(const wxString &id); - wxDataFormat(const QString &id); - wxDataFormat(const wxChar *id); - void SetId( const wxChar *id ); + // Standard methods + const wxString& GetId() const; + void SetId(const wxString& id); + + wxDataFormatId GetType() const; + void SetType(wxDataFormatId type); bool operator==(wxDataFormatId format) const; bool operator!=(wxDataFormatId format) const; bool operator==(const wxDataFormat& format) const; bool operator!=(const wxDataFormat& format) const; - // string ids are used for custom types - this SetId() must be used for - // application-specific formats - wxString GetId() const; - void SetId( const wxString& id ); + // Direct access to the underlying mime type. + // Equivalent to "id", except "id" is supposed to be + // invalid for standard types, whereas this should + // always be valid (if meaningful). + const wxString& GetMimeType() const; + void SetMimeType(const wxString& mimeType); - // implementation - wxDataFormatId GetType() const; - void SetType( wxDataFormatId type ); - - wxString m_MimeType; +private: + wxString m_mimeType; + wxDataFormatId m_formatId; }; #endif // _WX_QT_DATAFORM_H_ diff --git a/include/wx/qt/dataobj.h b/include/wx/qt/dataobj.h index 3ab0a7079b..ed4287c285 100644 --- a/include/wx/qt/dataobj.h +++ b/include/wx/qt/dataobj.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: src/qt/dataobj.cpp +// Name: src/qt/dataobj.h // Author: Peter Most // Copyright: (c) Peter Most // Licence: wxWindows licence @@ -8,24 +8,17 @@ #ifndef _WX_QT_DATAOBJ_H_ #define _WX_QT_DATAOBJ_H_ -class QMimeData; +// ---------------------------------------------------------------------------- +// wxDataObject is the same as wxDataObjectBase under wxQT +// ---------------------------------------------------------------------------- class WXDLLIMPEXP_CORE wxDataObject : public wxDataObjectBase { public: wxDataObject(); - ~wxDataObject(); + virtual ~wxDataObject(); - virtual bool IsSupportedFormat(const wxDataFormat& format, Direction dir) const; - virtual wxDataFormat GetPreferredFormat(Direction dir = Get) const; - virtual size_t GetFormatCount(Direction dir = Get) const; - virtual void GetAllFormats(wxDataFormat *formats, Direction dir = Get) const; - virtual size_t GetDataSize(const wxDataFormat& format) const; - virtual bool GetDataHere(const wxDataFormat& format, void *buf) const; - virtual bool SetData(const wxDataFormat& format, size_t len, const void * buf); - -private: - QMimeData *m_qtMimeData; // to handle formats that have no helper classes + virtual bool IsSupportedFormat( const wxDataFormat& format, Direction dir = Get ) const; }; #endif // _WX_QT_DATAOBJ_H_ diff --git a/include/wx/qt/dnd.h b/include/wx/qt/dnd.h index ca52754d6f..b497daf58e 100644 --- a/include/wx/qt/dnd.h +++ b/include/wx/qt/dnd.h @@ -8,39 +8,47 @@ #ifndef _WX_QT_DND_H_ #define _WX_QT_DND_H_ -#define wxDROP_ICON(name) wxICON(name) +#define wxDROP_ICON(name) wxCursor(name##_xpm) class WXDLLIMPEXP_CORE wxDropTarget : public wxDropTargetBase { public: - wxDropTarget(wxDataObject *dataObject = NULL ); + wxDropTarget(wxDataObject *dataObject = NULL); + virtual ~wxDropTarget(); - virtual bool OnDrop(wxCoord x, wxCoord y); - virtual wxDragResult OnData(wxCoord x, wxCoord y, wxDragResult def); - virtual bool GetData(); + virtual bool OnDrop(wxCoord x, wxCoord y) wxOVERRIDE; + virtual wxDragResult OnData(wxCoord x, + wxCoord y, + wxDragResult def) wxOVERRIDE; + virtual bool GetData() wxOVERRIDE; wxDataFormat GetMatchingPair(); -protected: + void ConnectTo(QWidget* widget); + void Disconnect(); private: + class Impl; + Impl* m_pImpl; }; - class WXDLLIMPEXP_CORE wxDropSource: public wxDropSourceBase { public: - wxDropSource( wxWindow *win = NULL, - const wxIcon © = wxNullIcon, - const wxIcon &move = wxNullIcon, - const wxIcon &none = wxNullIcon); + wxDropSource(wxWindow *win = NULL, + const wxCursor © = wxNullCursor, + const wxCursor &move = wxNullCursor, + const wxCursor &none = wxNullCursor); - wxDropSource( wxDataObject& data, - wxWindow *win, - const wxIcon © = wxNullIcon, - const wxIcon &move = wxNullIcon, - const wxIcon &none = wxNullIcon); + wxDropSource(wxDataObject& data, + wxWindow *win, + const wxCursor © = wxNullCursor, + const wxCursor &move = wxNullCursor, + const wxCursor &none = wxNullCursor); virtual wxDragResult DoDragDrop(int flags = wxDrag_CopyOnly); + +private: + wxWindow* m_parentWindow; }; #endif // _WX_QT_DND_H_ diff --git a/include/wx/qt/window.h b/include/wx/qt/window.h index a2f1542a27..6f5a2a87e1 100644 --- a/include/wx/qt/window.h +++ b/include/wx/qt/window.h @@ -9,8 +9,6 @@ #ifndef _WX_QT_WINDOW_H_ #define _WX_QT_WINDOW_H_ -#include - class QShortcut; template < class T > class QList; diff --git a/src/qt/clipbrd.cpp b/src/qt/clipbrd.cpp index 096685df0e..0a9dc2902d 100644 --- a/src/qt/clipbrd.cpp +++ b/src/qt/clipbrd.cpp @@ -109,7 +109,7 @@ bool wxClipboard::AddData( wxDataObject *data ) QByteArray bytearray(size, 0); data->GetDataHere(format, bytearray.data()); - MimeData->setData(wxQtConvertString(format.m_MimeType), bytearray); + MimeData->setData(wxQtConvertString(format.GetMimeType()), bytearray); } delete data; @@ -144,7 +144,7 @@ bool wxClipboard::GetData( wxDataObject& data ) const wxDataFormat format(formats[i]); // is this format supported by clipboard ? - if( !MimeData->hasFormat(wxQtConvertString(format.m_MimeType)) ) + if( !MimeData->hasFormat(wxQtConvertString(format.GetMimeType())) ) continue; wxTextDataObject *textdata = dynamic_cast(&data); @@ -152,7 +152,7 @@ bool wxClipboard::GetData( wxDataObject& data ) textdata->SetText(wxQtConvertString(MimeData->text())); else { - QByteArray bytearray = MimeData->data( wxQtConvertString(format.m_MimeType) ).data(); + QByteArray bytearray = MimeData->data( wxQtConvertString(format.GetMimeType()) ).data(); data.SetData(format, bytearray.size(), bytearray.constData()); } @@ -170,7 +170,7 @@ void wxClipboard::Clear() bool wxClipboard::IsSupported( const wxDataFormat& format ) { const QMimeData *data = QtClipboard->mimeData( (QClipboard::Mode)Mode() ); - return data->hasFormat(wxQtConvertString(format.m_MimeType)); + return data->hasFormat(wxQtConvertString(format.GetMimeType())); } bool wxClipboard::IsSupportedAsync(wxEvtHandler *sink) diff --git a/src/qt/dataobj.cpp b/src/qt/dataobj.cpp index 1d294fa72d..f8ba76bcc2 100644 --- a/src/qt/dataobj.cpp +++ b/src/qt/dataobj.cpp @@ -12,19 +12,16 @@ #pragma hdrstop #endif -#include "wx/qt/private/converter.h" -#include "wx/qt/private/utils.h" #include "wx/dataobj.h" +#include "wx/scopedarray.h" -#include - -wxDataFormat::wxDataFormat() +namespace { -} -static wxString DataFormatIdToMimeType( wxDataFormatId formatId ) +wxString DataFormatIdToMimeType(wxDataFormatId formatId) { - switch(formatId) { + switch ( formatId ) + { case wxDF_TEXT: return "text/plain"; case wxDF_BITMAP: return "image/bmp"; case wxDF_TIFF: return "image/tiff"; @@ -45,139 +42,115 @@ static wxString DataFormatIdToMimeType( wxDataFormatId formatId ) case wxDF_PRIVATE: case wxDF_INVALID: case wxDF_MAX: - break; + default: + return ""; } - return ""; } -wxDataFormat::wxDataFormat( wxDataFormatId formatId ) +} // anonymous namespace + +wxDataFormat::wxDataFormat(wxDataFormatId formatId) { - m_MimeType = DataFormatIdToMimeType(formatId); + SetType(formatId); } wxDataFormat::wxDataFormat(const wxString &id) { - m_MimeType = id; + SetId(id); } -wxDataFormat::wxDataFormat(const wxChar *id) +const wxString& wxDataFormat::GetMimeType() const { - m_MimeType = id; + return m_mimeType; } -wxDataFormat::wxDataFormat(const QString &id) +void wxDataFormat::SetMimeType(const wxString& mimeType) { - m_MimeType = wxQtConvertString(id); + m_mimeType = mimeType; + m_formatId = wxDF_INVALID; } -void wxDataFormat::SetId( const wxChar *id ) +void wxDataFormat::SetId(const wxString& id) { - m_MimeType = id; + SetMimeType(id); } -void wxDataFormat::SetId( const wxString& id ) +const wxString& wxDataFormat::GetId() const { - m_MimeType = id; -} - -wxString wxDataFormat::GetId() const -{ - return m_MimeType; + return m_mimeType; } wxDataFormatId wxDataFormat::GetType() const { - wxMISSING_IMPLEMENTATION( "wxDataFormat GetType" ); - return wxDataFormatId(); + return m_formatId; } -void wxDataFormat::SetType( wxDataFormatId WXUNUSED(type) ) +void wxDataFormat::SetType(wxDataFormatId formatId) { - wxMISSING_IMPLEMENTATION( "wxDataFormat SetType" ); + m_mimeType = DataFormatIdToMimeType(formatId); + m_formatId = formatId; } bool wxDataFormat::operator==(wxDataFormatId format) const { - return m_MimeType == DataFormatIdToMimeType(format); + return m_mimeType == DataFormatIdToMimeType(format) + && m_formatId == format; } bool wxDataFormat::operator!=(wxDataFormatId format) const { - return m_MimeType != DataFormatIdToMimeType(format); + return !operator==(format); } bool wxDataFormat::operator==(const wxDataFormat& format) const { - return m_MimeType == format.m_MimeType; + // If mime types match, then that's good enough. + // (Could be comparing a standard constructed format to a + // custom constructed one, where both are actually the same.) + if (!m_mimeType.empty() && m_mimeType == format.m_mimeType) + return true; + + return m_mimeType == format.m_mimeType + && m_formatId == format.m_formatId; } bool wxDataFormat::operator!=(const wxDataFormat& format) const { - return m_MimeType != format.m_MimeType; + return !operator==(format); } -//############################################################################# +//############################################################################ wxDataObject::wxDataObject() { - m_qtMimeData = new QMimeData; } wxDataObject::~wxDataObject() { - delete m_qtMimeData; } -bool wxDataObject::IsSupportedFormat(const wxDataFormat& format, Direction) const +bool wxDataObject::IsSupportedFormat(const wxDataFormat& format, + Direction dir) const { - return wxDataFormat(format) != wxDF_INVALID; -} -wxDataFormat wxDataObject::GetPreferredFormat(Direction) const -{ - /* formats are in order of preference */ - if (m_qtMimeData->formats().count()) - return m_qtMimeData->formats().first(); - - return wxDataFormat(); -} - -size_t wxDataObject::GetFormatCount(Direction) const -{ - return m_qtMimeData->formats().count(); -} - -void wxDataObject::GetAllFormats(wxDataFormat *formats, Direction) const -{ - int i = 0; - foreach (QString format, m_qtMimeData->formats()) + const size_t formatCount = GetFormatCount(dir); + if ( formatCount == 1 ) { - formats[i] = format; - i++; + return format == GetPreferredFormat(); } + + wxScopedArray formats(formatCount); + GetAllFormats(formats.get(), dir); + + for ( size_t n = 0; n < formatCount; ++n ) + { + if ( formats[n] == format ) + return true; + } + + return false; } -size_t wxDataObject::GetDataSize(const wxDataFormat& format) const -{ - return m_qtMimeData->data( wxQtConvertString(format.m_MimeType) ).count(); -} - -bool wxDataObject::GetDataHere(const wxDataFormat& format, void *buf) const -{ - if (!m_qtMimeData->hasFormat(wxQtConvertString(format.m_MimeType))) - return false; - - QByteArray data = m_qtMimeData->data( wxQtConvertString(format.m_MimeType) ).data(); - memcpy(buf, data.constData(), data.size()); - return true; -} - -bool wxDataObject::SetData(const wxDataFormat& format, size_t len, const void * buf) -{ - QByteArray bytearray((const char*)buf, len); - m_qtMimeData->setData(wxQtConvertString(format.m_MimeType), bytearray); - - return true; -} +//############################################################################ wxBitmapDataObject::wxBitmapDataObject() { @@ -187,6 +160,22 @@ wxBitmapDataObject::wxBitmapDataObject( const wxBitmap &WXUNUSED(bitmap) ) { } +//############################################################################# +// ---------------------------------------------------------------------------- +// wxTextDataObject +// --------------------------------------------------------------------------- + +#if wxUSE_UNICODE +void wxTextDataObject::GetAllFormats(wxDataFormat *formats, + wxDataObjectBase::Direction WXUNUSED(dir)) const +{ + formats[0] = wxDataFormat(wxDF_UNICODETEXT); + formats[1] = wxDataFormat(wxDF_TEXT); +} +#endif + +//############################################################################# + wxFileDataObject::wxFileDataObject() { } diff --git a/src/qt/dnd.cpp b/src/qt/dnd.cpp index 7e99e94ec2..4e5af17028 100644 --- a/src/qt/dnd.cpp +++ b/src/qt/dnd.cpp @@ -11,53 +11,380 @@ #if wxUSE_DRAG_AND_DROP #include "wx/dnd.h" +#include "wx/scopedarray.h" +#include "wx/window.h" -wxDropTarget::wxDropTarget(wxDataObject *WXUNUSED(dataObject)) +#include "wx/qt/private/converter.h" + +#include +#include +#include +#include + +namespace { + +wxDragResult DropActionToDragResult(Qt::DropAction action) +{ + switch ( action ) + { + case Qt::IgnoreAction: + return wxDragCancel; + case Qt::CopyAction: + return wxDragCopy; + case Qt::MoveAction: + case Qt::TargetMoveAction: + return wxDragMove; + case Qt::LinkAction: + return wxDragLink; + } + + wxFAIL_MSG("Illegal drop action"); + return wxDragNone; +} + +Qt::DropAction DragResultToDropAction(wxDragResult result) +{ + switch ( result ) + { + case wxDragCopy: + return Qt::CopyAction; + case wxDragMove: + return Qt::MoveAction; + case wxDragLink: + return Qt::LinkAction; + case wxDragError: + case wxDragNone: + case wxDragCancel: + return Qt::IgnoreAction; + } + + wxFAIL_MSG("Illegal drag result"); + return Qt::IgnoreAction; +} + +void AddDataFormat(wxDataObject* dataObject, + QMimeData* mimeData, + const wxDataFormat& format) +{ + const size_t data_size = dataObject->GetDataSize(format); + + QByteArray data(static_cast(data_size), Qt::Initialization()); + dataObject->GetDataHere(format, data.data()); + + mimeData->setData(wxQtConvertString(format.GetMimeType()), data); +} + +QMimeData* CreateMimeData(wxDataObject* dataObject) +{ + QMimeData* mimeData = new QMimeData(); + + const size_t count = dataObject->GetFormatCount(); + + wxScopedArray array(dataObject->GetFormatCount()); + dataObject->GetAllFormats(array.get()); + + for ( size_t i = 0; i < count; i++ ) + { + AddDataFormat(dataObject, mimeData, array[i]); + } + + return mimeData; +} + +void SetDragCursor(QDrag& drag, + const wxCursor& cursor, + Qt::DropAction action) +{ + if ( cursor.IsOk() ) + drag.setDragCursor(cursor.GetHandle().pixmap(), action); +} + +class PendingMimeDataSetter +{ +public: + PendingMimeDataSetter(const QMimeData*& targetMimeData, + const QMimeData* mimeData) + : m_targetMimeData(targetMimeData) + { + m_targetMimeData = mimeData; + } + + ~PendingMimeDataSetter() + { + m_targetMimeData = NULL; + } + +private: + const QMimeData*& m_targetMimeData; +}; + +} // anonymous namespace + +class wxDropTarget::Impl : public QObject +{ +public: + explicit Impl(wxDropTarget* dropTarget) + : m_dropTarget(dropTarget), + m_widget(NULL), + m_pendingMimeData(NULL) + { + } + + ~Impl() + { + Disconnect(); + } + + void ConnectTo(QWidget* widget) + { + Disconnect(); + + m_widget = widget; + + if ( m_widget != NULL ) + { + m_widget->setAcceptDrops(true); + m_widget->installEventFilter(this); + } + } + + void Disconnect() + { + if ( m_widget != NULL ) + { + m_widget->setAcceptDrops(false); + m_widget->removeEventFilter(this); + m_widget = NULL; + } + } + + virtual bool eventFilter(QObject* watched, QEvent* event) wxOVERRIDE + { + if ( m_dropTarget != NULL ) + { + switch ( event->type() ) + { + case QEvent::Drop: + OnDrop(event); + return true; + + case QEvent::DragEnter: + OnEnter(event); + return true; + + case QEvent::DragMove: + OnMove(event); + return true; + + case QEvent::DragLeave: + OnLeave(event); + return true; + + default: + break; + } + } + + return QObject::eventFilter(watched, event); + } + + void OnEnter(QEvent* event) + { + QDragEnterEvent *e = static_cast(event); + + const PendingMimeDataSetter setter(m_pendingMimeData, e->mimeData()); + + if ( !CanDropHere() ) + { + e->setDropAction(Qt::IgnoreAction); + return; + } + + event->accept(); + + const QPoint where = e->pos(); + const wxDragResult proposedResult = + DropActionToDragResult(e->proposedAction()); + const wxDragResult result = m_dropTarget->OnEnter(where.x(), + where.y(), + proposedResult); + + e->setDropAction(DragResultToDropAction(result)); + } + + void OnLeave(QEvent* event) + { + event->accept(); + m_dropTarget->OnLeave(); + } + + void OnMove(QEvent* event) + { + event->accept(); + + QDragMoveEvent *e = static_cast(event); + + const PendingMimeDataSetter setter(m_pendingMimeData, e->mimeData()); + + const QPoint where = e->pos(); + const wxDragResult proposedResult = + DropActionToDragResult(e->proposedAction()); + const wxDragResult result = m_dropTarget->OnDragOver(where.x(), + where.y(), + proposedResult); + + e->setDropAction(DragResultToDropAction(result)); + } + + void OnDrop(QEvent* event) + { + event->accept(); + + const QDropEvent *e = static_cast(event); + + const PendingMimeDataSetter setter(m_pendingMimeData, e->mimeData()); + + const QPoint where = e->pos(); + if ( m_dropTarget->OnDrop(where.x(), where.y()) ) + { + m_dropTarget->OnData(where.x(), + where.y(), + DropActionToDragResult(e->dropAction())); + } + } + + const QMimeData* GetMimeData() const + { + return m_pendingMimeData; + } + +private: + + bool CanDropHere() const + { + return !m_dropTarget->GetMatchingPair().GetMimeType().empty(); + } + + wxDropTarget* m_dropTarget; + QWidget* m_widget; + const QMimeData* m_pendingMimeData; +}; + +wxDropTarget::wxDropTarget(wxDataObject *dataObject) + : wxDropTargetBase(dataObject), + m_pImpl(new Impl(this)) +{ +} + +wxDropTarget::~wxDropTarget() +{ + delete m_pImpl; } bool wxDropTarget::OnDrop(wxCoord WXUNUSED(x), wxCoord WXUNUSED(y)) { - return false; + return true; } -wxDragResult wxDropTarget::OnData(wxCoord WXUNUSED(x), wxCoord WXUNUSED(y), wxDragResult WXUNUSED(def)) +wxDragResult wxDropTarget::OnData(wxCoord WXUNUSED(x), + wxCoord WXUNUSED(y), + wxDragResult def) { - return wxDragResult(); + return GetData() ? def : wxDragNone; } bool wxDropTarget::GetData() { - return false; + const wxDataFormat droppedFormat = GetMatchingPair(); + + const wxString& mimeType = droppedFormat.GetMimeType(); + if ( mimeType.empty() ) + return false; + + const QString qMimeType = wxQtConvertString(mimeType); + const QByteArray data = m_pImpl->GetMimeData()->data(qMimeType); + + return m_dataObject->SetData(droppedFormat, data.size(), data.data()); } wxDataFormat wxDropTarget::GetMatchingPair() { - wxFAIL_MSG("wxDropTarget::GetMatchingPair() not implemented in src/qt/dnd.cpp"); - return wxDF_INVALID; + const QMimeData* mimeData = m_pImpl->GetMimeData(); + if ( mimeData == NULL || m_dataObject == NULL ) + return wxFormatInvalid; + + const QStringList formats = mimeData->formats(); + for ( int i = 0; i < formats.count(); ++i ) + { + const wxDataFormat format(wxQtConvertString(formats[i])); + + if ( m_dataObject->IsSupportedFormat(format) ) + { + return format; + } + } + return wxFormatInvalid; } -//############################################################################## +void wxDropTarget::ConnectTo(QWidget* widget) +{ + m_pImpl->ConnectTo(widget); +} +void wxDropTarget::Disconnect() +{ + m_pImpl->Disconnect(); +} -wxDropSource::wxDropSource( wxWindow *WXUNUSED(win), - const wxIcon &WXUNUSED(copy), - const wxIcon &WXUNUSED(move), - const wxIcon &WXUNUSED(none)) +//########################################################################### + +wxDropSource::wxDropSource(wxWindow *win, + const wxCursor ©, + const wxCursor &move, + const wxCursor &none) + : wxDropSourceBase(copy, move, none), + m_parentWindow(win) { } -wxDropSource::wxDropSource( wxDataObject& WXUNUSED(data), - wxWindow *WXUNUSED(win), - const wxIcon &WXUNUSED(copy), - const wxIcon &WXUNUSED(move), - const wxIcon &WXUNUSED(none)) +wxDropSource::wxDropSource(wxDataObject& data, + wxWindow *win, + const wxCursor ©, + const wxCursor &move, + const wxCursor &none) + : wxDropSourceBase(copy, move, none), + m_parentWindow(win) { + SetData(data); } -wxDragResult wxDropSource::DoDragDrop(int WXUNUSED(flags)) +wxDragResult wxDropSource::DoDragDrop(int flags /*=wxDrag_CopyOnly*/) { - return wxDragResult(); + wxCHECK_MSG(m_data != NULL, wxDragNone, + wxT("No data in wxDropSource!")); + + wxCHECK_MSG(m_parentWindow != NULL, wxDragNone, + wxT("NULL parent window in wxDropSource!")); + + QDrag drag(m_parentWindow->GetHandle()); + drag.setMimeData(CreateMimeData(m_data)); + + SetDragCursor(drag, m_cursorCopy, Qt::CopyAction); + SetDragCursor(drag, m_cursorMove, Qt::MoveAction); + SetDragCursor(drag, m_cursorStop, Qt::IgnoreAction); + + const Qt::DropActions actions = + flags == wxDrag_CopyOnly + ? Qt::CopyAction + : Qt::CopyAction | Qt::MoveAction; + + const Qt::DropAction defaultAction = + flags == wxDrag_DefaultMove + ? Qt::MoveAction + : Qt::CopyAction; + + return DropActionToDragResult(drag.exec(actions, defaultAction)); } #endif // wxUSE_DRAG_AND_DROP diff --git a/src/qt/window.cpp b/src/qt/window.cpp index 0ca75db5a3..21dea1b8f3 100644 --- a/src/qt/window.cpp +++ b/src/qt/window.cpp @@ -31,12 +31,12 @@ #endif // WX_PRECOMP #include "wx/window.h" +#include "wx/dnd.h" #include "wx/tooltip.h" #include "wx/qt/private/utils.h" #include "wx/qt/private/converter.h" #include "wx/qt/private/winevent.h" - #define VERT_SCROLLBAR_POSITION 0, 1 #define HORZ_SCROLLBAR_POSITION 1, 0 @@ -193,9 +193,6 @@ static const char WINDOW_POINTER_PROPERTY_NAME[] = "wxWindowPointer"; return const_cast< wxWindowQt * >( ( variant.value< const wxWindow * >() )); } - - - static wxWindowQt *s_capturedWindow = NULL; /* static */ wxWindowQt *wxWindowBase::DoFindFocus() @@ -225,6 +222,8 @@ void wxWindowQt::Init() #endif m_qtWindow = NULL; m_qtContainer = NULL; + + m_dropTarget = NULL; } wxWindowQt::wxWindowQt() @@ -260,6 +259,10 @@ wxWindowQt::~wxWindowQt() delete m_qtShortcuts; #endif +#if wxUSE_DRAG_AND_DROP + SetDropTarget(NULL); +#endif + // Delete only if the qt widget was created or assigned to this base class if (m_qtWindow) { @@ -696,9 +699,22 @@ void wxWindowQt::ScrollWindow( int dx, int dy, const wxRect *rect ) #if wxUSE_DRAG_AND_DROP -void wxWindowQt::SetDropTarget( wxDropTarget * WXUNUSED( dropTarget ) ) +void wxWindowQt::SetDropTarget( wxDropTarget *dropTarget ) { - wxMISSING_IMPLEMENTATION( __FUNCTION__ ); + if ( m_dropTarget == dropTarget ) + return; + + if ( m_dropTarget != NULL ) + { + m_dropTarget->Disconnect(); + } + + m_dropTarget = dropTarget; + + if ( m_dropTarget != NULL ) + { + m_dropTarget->ConnectTo(m_qtWindow); + } } #endif