Implement initial try of wxDropTarget.
The drop target needs to use an event filter to capture drag-and-drop events from the window.
This commit is contained in:
@@ -10,22 +10,30 @@
|
|||||||
|
|
||||||
#define wxDROP_ICON(name) wxICON(name)
|
#define wxDROP_ICON(name) wxICON(name)
|
||||||
|
|
||||||
|
class QMimeData;
|
||||||
|
|
||||||
class WXDLLIMPEXP_CORE wxDropTarget : public wxDropTargetBase
|
class WXDLLIMPEXP_CORE wxDropTarget : public wxDropTargetBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
wxDropTarget(wxDataObject *dataObject = NULL );
|
wxDropTarget(wxDataObject *dataObject = NULL);
|
||||||
|
|
||||||
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, wxCoord y, wxDragResult def) wxOVERRIDE;
|
||||||
virtual bool GetData();
|
virtual bool GetData() wxOVERRIDE;
|
||||||
|
|
||||||
wxDataFormat GetMatchingPair();
|
wxDataFormat GetMatchingPair();
|
||||||
|
|
||||||
protected:
|
void OnQtEnter(QEvent* event);
|
||||||
|
void OnQtLeave(QEvent* event);
|
||||||
|
void OnQtMove(QEvent* event);
|
||||||
|
void OnQtDrop(QEvent* event);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
};
|
class PendingMimeDataSetter;
|
||||||
|
friend class PendingMimeDataSetter;
|
||||||
|
|
||||||
|
const QMimeData* m_pendingMimeData;
|
||||||
|
};
|
||||||
|
|
||||||
class WXDLLIMPEXP_CORE wxDropSource: public wxDropSourceBase
|
class WXDLLIMPEXP_CORE wxDropSource: public wxDropSourceBase
|
||||||
{
|
{
|
||||||
|
@@ -10,6 +10,7 @@
|
|||||||
#define _WX_QT_WINDOW_H_
|
#define _WX_QT_WINDOW_H_
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
class QShortcut;
|
class QShortcut;
|
||||||
template < class T > class QList;
|
template < class T > class QList;
|
||||||
@@ -216,6 +217,16 @@ protected:
|
|||||||
QWidget *m_qtWindow;
|
QWidget *m_qtWindow;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
class DnDEventAdapter : public QObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DnDEventAdapter();
|
||||||
|
virtual bool eventFilter(QObject* watched, QEvent* event);
|
||||||
|
void SetDropTarget(wxDropTarget* dropTarget, QWidget* window);
|
||||||
|
private:
|
||||||
|
wxDropTarget *m_dropTarget;
|
||||||
|
};
|
||||||
|
|
||||||
void Init();
|
void Init();
|
||||||
QScrollArea *m_qtContainer;
|
QScrollArea *m_qtContainer;
|
||||||
|
|
||||||
@@ -238,6 +249,10 @@ private:
|
|||||||
bool m_processingShortcut;
|
bool m_processingShortcut;
|
||||||
#endif // wxUSE_ACCEL
|
#endif // wxUSE_ACCEL
|
||||||
|
|
||||||
|
#if wxUSE_DRAG_AND_DROP
|
||||||
|
DnDEventAdapter dnd_event_adapter;
|
||||||
|
#endif
|
||||||
|
|
||||||
wxDECLARE_DYNAMIC_CLASS_NO_COPY( wxWindowQt );
|
wxDECLARE_DYNAMIC_CLASS_NO_COPY( wxWindowQt );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -102,6 +102,12 @@ bool wxDataFormat::operator!=(wxDataFormatId format) const
|
|||||||
|
|
||||||
bool wxDataFormat::operator==(const wxDataFormat& format) const
|
bool wxDataFormat::operator==(const wxDataFormat& format) const
|
||||||
{
|
{
|
||||||
|
// 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
|
return m_mimeType == format.m_mimeType
|
||||||
&& m_formatId == format.m_formatId;
|
&& m_formatId == format.m_formatId;
|
||||||
}
|
}
|
||||||
|
119
src/qt/dnd.cpp
119
src/qt/dnd.cpp
@@ -18,6 +18,7 @@
|
|||||||
#include <QDrag>
|
#include <QDrag>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QMimeData>
|
#include <QMimeData>
|
||||||
|
#include <QCloseEvent>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@@ -38,6 +39,21 @@ namespace
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Qt::DropAction DragResultToDropAction(wxDragResult result)
|
||||||
|
{
|
||||||
|
switch ( result )
|
||||||
|
{
|
||||||
|
case wxDragCopy:
|
||||||
|
return Qt::CopyAction;
|
||||||
|
case wxDragMove:
|
||||||
|
return Qt::MoveAction;
|
||||||
|
case wxDragLink:
|
||||||
|
return Qt::LinkAction;
|
||||||
|
default:
|
||||||
|
return Qt::IgnoreAction;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void AddDataFormat(wxDataObject* dataObject, QMimeData* mimeData, const wxDataFormat& format)
|
void AddDataFormat(wxDataObject* dataObject, QMimeData* mimeData, const wxDataFormat& format)
|
||||||
{
|
{
|
||||||
const size_t data_size = dataObject->GetDataSize(format);
|
const size_t data_size = dataObject->GetDataSize(format);
|
||||||
@@ -66,29 +82,120 @@ namespace
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wxDropTarget::wxDropTarget(wxDataObject *WXUNUSED(dataObject))
|
class wxDropTarget::PendingMimeDataSetter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PendingMimeDataSetter(wxDropTarget* dropTarget, const QMimeData* mimeData)
|
||||||
|
: m_dropTarget(dropTarget)
|
||||||
|
{
|
||||||
|
m_dropTarget->m_pendingMimeData = mimeData;
|
||||||
|
}
|
||||||
|
|
||||||
|
~PendingMimeDataSetter()
|
||||||
|
{
|
||||||
|
m_dropTarget->m_pendingMimeData = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
wxDropTarget* m_dropTarget;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
wxDropTarget::wxDropTarget(wxDataObject *dataObject)
|
||||||
|
: wxDropTargetBase(dataObject),
|
||||||
|
m_pendingMimeData(NULL)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxDropTarget::OnDrop(wxCoord WXUNUSED(x), wxCoord WXUNUSED(y))
|
bool wxDropTarget::OnDrop(wxCoord WXUNUSED(x), wxCoord WXUNUSED(y))
|
||||||
{
|
{
|
||||||
return false;
|
return !GetMatchingPair().GetMimeType().empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
wxDragResult wxDropTarget::OnData(wxCoord WXUNUSED(x), wxCoord WXUNUSED(y), wxDragResult WXUNUSED(def))
|
wxDragResult wxDropTarget::OnData(wxCoord WXUNUSED(x), wxCoord WXUNUSED(y), wxDragResult default_drag_result)
|
||||||
{
|
{
|
||||||
return wxDragResult();
|
GetData();
|
||||||
|
return default_drag_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxDropTarget::GetData()
|
bool wxDropTarget::GetData()
|
||||||
{
|
{
|
||||||
|
const wxDataFormat droppedFormat = GetMatchingPair();
|
||||||
|
|
||||||
|
const wxString mimeType = droppedFormat.GetMimeType();
|
||||||
|
if ( mimeType.empty() )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
const QByteArray data = m_pendingMimeData->data(wxQtConvertString(mimeType));
|
||||||
|
|
||||||
|
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");
|
if ( m_pendingMimeData == NULL || m_dataObject == NULL )
|
||||||
return wxDF_INVALID;
|
return wxFormatInvalid;
|
||||||
|
|
||||||
|
const QStringList formats = m_pendingMimeData->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::OnQtEnter(QEvent* event)
|
||||||
|
{
|
||||||
|
event->accept();
|
||||||
|
|
||||||
|
QDragEnterEvent *e = static_cast<QDragEnterEvent*>(event);
|
||||||
|
const QPoint where = e->pos();
|
||||||
|
|
||||||
|
PendingMimeDataSetter setter(this, e->mimeData());
|
||||||
|
|
||||||
|
wxDragResult result = OnEnter(where.x(), where.y(), DropActionToDragResult(e->proposedAction()));
|
||||||
|
|
||||||
|
e->setDropAction(DragResultToDropAction(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxDropTarget::OnQtLeave(QEvent* event)
|
||||||
|
{
|
||||||
|
event->accept();
|
||||||
|
OnLeave();
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxDropTarget::OnQtMove(QEvent* event)
|
||||||
|
{
|
||||||
|
event->accept();
|
||||||
|
|
||||||
|
QDragMoveEvent *e = static_cast<QDragMoveEvent*>(event);
|
||||||
|
const QPoint where = e->pos();
|
||||||
|
|
||||||
|
PendingMimeDataSetter setter(this, e->mimeData());
|
||||||
|
|
||||||
|
wxDragResult result = OnDragOver(where.x(), where.y(), DropActionToDragResult(e->proposedAction()));
|
||||||
|
|
||||||
|
e->setDropAction(DragResultToDropAction(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxDropTarget::OnQtDrop(QEvent* event)
|
||||||
|
{
|
||||||
|
event->accept();
|
||||||
|
|
||||||
|
const QDropEvent *e = static_cast<QDropEvent*>(event);
|
||||||
|
const QPoint where = e->pos();
|
||||||
|
|
||||||
|
PendingMimeDataSetter setter(this, e->mimeData());
|
||||||
|
|
||||||
|
if ( OnDrop(where.x(), where.y()) )
|
||||||
|
{
|
||||||
|
OnData(where.x(), where.y(), DropActionToDragResult(e->dropAction()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//##############################################################################
|
//##############################################################################
|
||||||
|
@@ -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()
|
||||||
@@ -688,9 +687,9 @@ 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__ );
|
dnd_event_adapter.SetDropTarget(dropTarget, m_qtWindow);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1543,3 +1542,60 @@ QPainter *wxWindowQt::QtGetPainter()
|
|||||||
{
|
{
|
||||||
return m_qtPainter;
|
return m_qtPainter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//##############################################################################
|
||||||
|
// DnDEventAdapter
|
||||||
|
//##############################################################################
|
||||||
|
|
||||||
|
wxWindow::DnDEventAdapter::DnDEventAdapter() : m_dropTarget(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxWindow::DnDEventAdapter::eventFilter(QObject* watched, QEvent* event)
|
||||||
|
{
|
||||||
|
if ( m_dropTarget != NULL )
|
||||||
|
{
|
||||||
|
switch ( event->type() )
|
||||||
|
{
|
||||||
|
case QEvent::Drop:
|
||||||
|
m_dropTarget->OnQtDrop(event);
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case QEvent::DragEnter:
|
||||||
|
m_dropTarget->OnQtEnter(event);
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case QEvent::DragMove:
|
||||||
|
m_dropTarget->OnQtMove(event);
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case QEvent::DragLeave:
|
||||||
|
m_dropTarget->OnQtLeave(event);
|
||||||
|
return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return QObject::eventFilter(watched, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxWindow::DnDEventAdapter::SetDropTarget(wxDropTarget* dropTarget, QWidget* window)
|
||||||
|
{
|
||||||
|
if ( m_dropTarget == dropTarget )
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_dropTarget = dropTarget;
|
||||||
|
|
||||||
|
if ( m_dropTarget == NULL )
|
||||||
|
{
|
||||||
|
window->removeEventFilter(this);
|
||||||
|
window->setAcceptDrops(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
window->installEventFilter(this);
|
||||||
|
window->setAcceptDrops(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user