Merge branch 'qt-dnd'

Initial drag-and-drop implementation for wxQt.

Closes https://github.com/wxWidgets/wxWidgets/pull/1205
This commit is contained in:
Vadim Zeitlin
2019-02-02 15:54:21 +01:00
9 changed files with 491 additions and 160 deletions

View File

@@ -322,7 +322,7 @@ private:
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
#if wxUSE_UNICODE #if wxUSE_UNICODE
#if defined(__WXGTK20__) || defined(__WXX11__) #if defined(__WXGTK20__) || defined(__WXX11__) || defined(__WXQT__)
#define wxNEEDS_UTF8_FOR_TEXT_DATAOBJ #define wxNEEDS_UTF8_FOR_TEXT_DATAOBJ
#elif defined(__WXMAC__) #elif defined(__WXMAC__)
#define wxNEEDS_UTF16_FOR_TEXT_DATAOBJ #define wxNEEDS_UTF16_FOR_TEXT_DATAOBJ

View File

@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// Name: wx/qt/toolbar.h // Name: wx/qt/dataform.h
// Author: Sean D'Epagnier // Author: Sean D'Epagnier
// Copyright: (c) Sean D'Epagnier 2014 // Copyright: (c) Sean D'Epagnier 2014
// Licence: wxWindows licence // Licence: wxWindows licence
@@ -8,34 +8,34 @@
#ifndef _WX_QT_DATAFORM_H_ #ifndef _WX_QT_DATAFORM_H_
#define _WX_QT_DATAFORM_H_ #define _WX_QT_DATAFORM_H_
class QString;
class WXDLLIMPEXP_CORE wxDataFormat class WXDLLIMPEXP_CORE wxDataFormat
{ {
public: public:
wxDataFormat(); wxDataFormat(wxDataFormatId formatId = wxDF_INVALID);
wxDataFormat( wxDataFormatId formatId );
wxDataFormat(const wxString &id); 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!=(wxDataFormatId format) const; bool operator!=(wxDataFormatId format) const;
bool operator==(const wxDataFormat& format) const; bool operator==(const wxDataFormat& 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 // Direct access to the underlying mime type.
// application-specific formats // Equivalent to "id", except "id" is supposed to be
wxString GetId() const; // invalid for standard types, whereas this should
void SetId( const wxString& id ); // always be valid (if meaningful).
const wxString& GetMimeType() const;
void SetMimeType(const wxString& mimeType);
// implementation private:
wxDataFormatId GetType() const; wxString m_mimeType;
void SetType( wxDataFormatId type ); wxDataFormatId m_formatId;
wxString m_MimeType;
}; };
#endif // _WX_QT_DATAFORM_H_ #endif // _WX_QT_DATAFORM_H_

View File

@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// Name: src/qt/dataobj.cpp // Name: src/qt/dataobj.h
// Author: Peter Most // Author: Peter Most
// Copyright: (c) Peter Most // Copyright: (c) Peter Most
// Licence: wxWindows licence // Licence: wxWindows licence
@@ -8,24 +8,17 @@
#ifndef _WX_QT_DATAOBJ_H_ #ifndef _WX_QT_DATAOBJ_H_
#define _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 class WXDLLIMPEXP_CORE wxDataObject : public wxDataObjectBase
{ {
public: public:
wxDataObject(); wxDataObject();
~wxDataObject(); virtual ~wxDataObject();
virtual bool IsSupportedFormat(const wxDataFormat& format, Direction dir) const; virtual bool IsSupportedFormat( const wxDataFormat& format, Direction dir = Get ) 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
}; };
#endif // _WX_QT_DATAOBJ_H_ #endif // _WX_QT_DATAOBJ_H_

View File

@@ -8,39 +8,47 @@
#ifndef _WX_QT_DND_H_ #ifndef _WX_QT_DND_H_
#define _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 class WXDLLIMPEXP_CORE wxDropTarget : public wxDropTargetBase
{ {
public: public:
wxDropTarget(wxDataObject *dataObject = NULL ); wxDropTarget(wxDataObject *dataObject = NULL);
virtual ~wxDropTarget();
virtual bool OnDrop(wxCoord x, wxCoord y); virtual bool OnDrop(wxCoord x, wxCoord y) wxOVERRIDE;
virtual wxDragResult OnData(wxCoord x, wxCoord y, wxDragResult def); virtual wxDragResult OnData(wxCoord x,
virtual bool GetData(); wxCoord y,
wxDragResult def) wxOVERRIDE;
virtual bool GetData() wxOVERRIDE;
wxDataFormat GetMatchingPair(); wxDataFormat GetMatchingPair();
protected: void ConnectTo(QWidget* widget);
void Disconnect();
private: private:
class Impl;
Impl* m_pImpl;
}; };
class WXDLLIMPEXP_CORE wxDropSource: public wxDropSourceBase class WXDLLIMPEXP_CORE wxDropSource: public wxDropSourceBase
{ {
public: public:
wxDropSource( wxWindow *win = NULL, wxDropSource(wxWindow *win = NULL,
const wxIcon &copy = wxNullIcon, const wxCursor &copy = wxNullCursor,
const wxIcon &move = wxNullIcon, const wxCursor &move = wxNullCursor,
const wxIcon &none = wxNullIcon); const wxCursor &none = wxNullCursor);
wxDropSource( wxDataObject& data, wxDropSource(wxDataObject& data,
wxWindow *win, wxWindow *win,
const wxIcon &copy = wxNullIcon, const wxCursor &copy = wxNullCursor,
const wxIcon &move = wxNullIcon, const wxCursor &move = wxNullCursor,
const wxIcon &none = wxNullIcon); const wxCursor &none = wxNullCursor);
virtual wxDragResult DoDragDrop(int flags = wxDrag_CopyOnly); virtual wxDragResult DoDragDrop(int flags = wxDrag_CopyOnly);
private:
wxWindow* m_parentWindow;
}; };
#endif // _WX_QT_DND_H_ #endif // _WX_QT_DND_H_

View File

@@ -9,8 +9,6 @@
#ifndef _WX_QT_WINDOW_H_ #ifndef _WX_QT_WINDOW_H_
#define _WX_QT_WINDOW_H_ #define _WX_QT_WINDOW_H_
#include <list>
class QShortcut; class QShortcut;
template < class T > class QList; template < class T > class QList;

View File

@@ -109,7 +109,7 @@ bool wxClipboard::AddData( wxDataObject *data )
QByteArray bytearray(size, 0); QByteArray bytearray(size, 0);
data->GetDataHere(format, bytearray.data()); data->GetDataHere(format, bytearray.data());
MimeData->setData(wxQtConvertString(format.m_MimeType), bytearray); MimeData->setData(wxQtConvertString(format.GetMimeType()), bytearray);
} }
delete data; delete data;
@@ -144,7 +144,7 @@ bool wxClipboard::GetData( wxDataObject& data )
const wxDataFormat format(formats[i]); const wxDataFormat format(formats[i]);
// is this format supported by clipboard ? // is this format supported by clipboard ?
if( !MimeData->hasFormat(wxQtConvertString(format.m_MimeType)) ) if( !MimeData->hasFormat(wxQtConvertString(format.GetMimeType())) )
continue; continue;
wxTextDataObject *textdata = dynamic_cast<wxTextDataObject*>(&data); wxTextDataObject *textdata = dynamic_cast<wxTextDataObject*>(&data);
@@ -152,7 +152,7 @@ bool wxClipboard::GetData( wxDataObject& data )
textdata->SetText(wxQtConvertString(MimeData->text())); textdata->SetText(wxQtConvertString(MimeData->text()));
else 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()); data.SetData(format, bytearray.size(), bytearray.constData());
} }
@@ -170,7 +170,7 @@ void wxClipboard::Clear()
bool wxClipboard::IsSupported( const wxDataFormat& format ) bool wxClipboard::IsSupported( const wxDataFormat& format )
{ {
const QMimeData *data = QtClipboard->mimeData( (QClipboard::Mode)Mode() ); 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) bool wxClipboard::IsSupportedAsync(wxEvtHandler *sink)

View File

@@ -12,19 +12,16 @@
#pragma hdrstop #pragma hdrstop
#endif #endif
#include "wx/qt/private/converter.h"
#include "wx/qt/private/utils.h"
#include "wx/dataobj.h" #include "wx/dataobj.h"
#include "wx/scopedarray.h"
#include <QtCore/QMimeData> namespace
wxDataFormat::wxDataFormat()
{ {
}
static wxString DataFormatIdToMimeType( wxDataFormatId formatId ) wxString DataFormatIdToMimeType(wxDataFormatId formatId)
{ {
switch(formatId) { switch ( formatId )
{
case wxDF_TEXT: return "text/plain"; case wxDF_TEXT: return "text/plain";
case wxDF_BITMAP: return "image/bmp"; case wxDF_BITMAP: return "image/bmp";
case wxDF_TIFF: return "image/tiff"; case wxDF_TIFF: return "image/tiff";
@@ -45,139 +42,115 @@ static wxString DataFormatIdToMimeType( wxDataFormatId formatId )
case wxDF_PRIVATE: case wxDF_PRIVATE:
case wxDF_INVALID: case wxDF_INVALID:
case wxDF_MAX: 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) 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; return m_mimeType;
}
wxString wxDataFormat::GetId() const
{
return m_MimeType;
} }
wxDataFormatId wxDataFormat::GetType() const wxDataFormatId wxDataFormat::GetType() const
{ {
wxMISSING_IMPLEMENTATION( "wxDataFormat GetType" ); return m_formatId;
return wxDataFormatId();
} }
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 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 bool wxDataFormat::operator!=(wxDataFormatId format) const
{ {
return m_MimeType != DataFormatIdToMimeType(format); return !operator==(format);
} }
bool wxDataFormat::operator==(const wxDataFormat& format) const 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 bool wxDataFormat::operator!=(const wxDataFormat& format) const
{ {
return m_MimeType != format.m_MimeType; return !operator==(format);
} }
//############################################################################# //############################################################################
wxDataObject::wxDataObject() wxDataObject::wxDataObject()
{ {
m_qtMimeData = new QMimeData;
} }
wxDataObject::~wxDataObject() 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; const size_t formatCount = GetFormatCount(dir);
} if ( formatCount == 1 )
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())
{ {
formats[i] = format; return format == GetPreferredFormat();
i++;
} }
wxScopedArray<wxDataFormat> 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() 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() wxFileDataObject::wxFileDataObject()
{ {
} }

View File

@@ -11,53 +11,380 @@
#if wxUSE_DRAG_AND_DROP #if wxUSE_DRAG_AND_DROP
#include "wx/dnd.h" #include "wx/dnd.h"
#include "wx/scopedarray.h"
#include "wx/window.h"
wxDropTarget::wxDropTarget(wxDataObject *WXUNUSED(dataObject)) #include "wx/qt/private/converter.h"
#include <QDrag>
#include <QWidget>
#include <QMimeData>
#include <QCloseEvent>
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<int>(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<wxDataFormat> 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<QDragEnterEvent*>(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<QDragMoveEvent*>(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<QDropEvent*>(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)) 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() 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() wxDataFormat wxDropTarget::GetMatchingPair()
{ {
wxFAIL_MSG("wxDropTarget::GetMatchingPair() not implemented in src/qt/dnd.cpp"); const QMimeData* mimeData = m_pImpl->GetMimeData();
return wxDF_INVALID; 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), wxDropSource::wxDropSource(wxWindow *win,
const wxIcon &WXUNUSED(none)) const wxCursor &copy,
const wxCursor &move,
const wxCursor &none)
: wxDropSourceBase(copy, move, none),
m_parentWindow(win)
{ {
} }
wxDropSource::wxDropSource( wxDataObject& WXUNUSED(data), wxDropSource::wxDropSource(wxDataObject& data,
wxWindow *WXUNUSED(win), wxWindow *win,
const wxIcon &WXUNUSED(copy), const wxCursor &copy,
const wxIcon &WXUNUSED(move), const wxCursor &move,
const wxIcon &WXUNUSED(none)) 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 #endif // wxUSE_DRAG_AND_DROP

View File

@@ -31,12 +31,12 @@
#endif // WX_PRECOMP #endif // WX_PRECOMP
#include "wx/window.h" #include "wx/window.h"
#include "wx/dnd.h"
#include "wx/tooltip.h" #include "wx/tooltip.h"
#include "wx/qt/private/utils.h" #include "wx/qt/private/utils.h"
#include "wx/qt/private/converter.h" #include "wx/qt/private/converter.h"
#include "wx/qt/private/winevent.h" #include "wx/qt/private/winevent.h"
#define VERT_SCROLLBAR_POSITION 0, 1 #define VERT_SCROLLBAR_POSITION 0, 1
#define HORZ_SCROLLBAR_POSITION 1, 0 #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 * >() )); return const_cast< wxWindowQt * >( ( variant.value< const wxWindow * >() ));
} }
static wxWindowQt *s_capturedWindow = NULL; static wxWindowQt *s_capturedWindow = NULL;
/* static */ wxWindowQt *wxWindowBase::DoFindFocus() /* static */ wxWindowQt *wxWindowBase::DoFindFocus()
@@ -225,6 +222,8 @@ void wxWindowQt::Init()
#endif #endif
m_qtWindow = NULL; m_qtWindow = NULL;
m_qtContainer = NULL; m_qtContainer = NULL;
m_dropTarget = NULL;
} }
wxWindowQt::wxWindowQt() wxWindowQt::wxWindowQt()
@@ -260,6 +259,10 @@ wxWindowQt::~wxWindowQt()
delete m_qtShortcuts; delete m_qtShortcuts;
#endif #endif
#if wxUSE_DRAG_AND_DROP
SetDropTarget(NULL);
#endif
// Delete only if the qt widget was created or assigned to this base class // Delete only if the qt widget was created or assigned to this base class
if (m_qtWindow) if (m_qtWindow)
{ {
@@ -696,9 +699,22 @@ void wxWindowQt::ScrollWindow( int dx, int dy, const wxRect *rect )
#if wxUSE_DRAG_AND_DROP #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 #endif