Merge branch 'qt-dnd'
Initial drag-and-drop implementation for wxQt. Closes https://github.com/wxWidgets/wxWidgets/pull/1205
This commit is contained in:
@@ -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
|
||||||
|
@@ -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_
|
||||||
|
@@ -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_
|
||||||
|
@@ -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 © = wxNullIcon,
|
const wxCursor © = 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 © = wxNullIcon,
|
const wxCursor © = 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_
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
|
@@ -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)
|
||||||
|
@@ -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 "";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
wxDataFormat::wxDataFormat(wxDataFormatId formatId)
|
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 )
|
|
||||||
{
|
|
||||||
m_MimeType = id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxDataFormat::SetId(const wxString& id)
|
void wxDataFormat::SetId(const wxString& id)
|
||||||
{
|
{
|
||||||
m_MimeType = id;
|
SetMimeType(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString wxDataFormat::GetId() const
|
const wxString& wxDataFormat::GetId() const
|
||||||
{
|
{
|
||||||
return m_MimeType;
|
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 */
|
return format == GetPreferredFormat();
|
||||||
if (m_qtMimeData->formats().count())
|
|
||||||
return m_qtMimeData->formats().first();
|
|
||||||
|
|
||||||
return wxDataFormat();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t wxDataObject::GetFormatCount(Direction) const
|
wxScopedArray<wxDataFormat> formats(formatCount);
|
||||||
|
GetAllFormats(formats.get(), dir);
|
||||||
|
|
||||||
|
for ( size_t n = 0; n < formatCount; ++n )
|
||||||
{
|
{
|
||||||
return m_qtMimeData->formats().count();
|
if ( formats[n] == format )
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxDataObject::GetAllFormats(wxDataFormat *formats, Direction) const
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
foreach (QString format, m_qtMimeData->formats())
|
|
||||||
{
|
|
||||||
formats[i] = format;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
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()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
363
src/qt/dnd.cpp
363
src/qt/dnd.cpp
@@ -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()
|
||||||
{
|
{
|
||||||
|
const wxDataFormat droppedFormat = GetMatchingPair();
|
||||||
|
|
||||||
|
const wxString& mimeType = droppedFormat.GetMimeType();
|
||||||
|
if ( mimeType.empty() )
|
||||||
return false;
|
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 ©,
|
||||||
|
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 ©,
|
||||||
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
|
||||||
|
@@ -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
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user