summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Krammer <kevin.krammer.qnx@kdab.com>2012-03-05 16:00:41 (GMT)
committerQt by Nokia <qt-info@nokia.com>2012-03-06 23:42:17 (GMT)
commit547b43c7422559410f9dd8e410105ee97773f353 (patch)
tree82c91dd8f5b48ec91f0ba2ad69681be80e81cc89
parent821fc4cf4e520a74b8d4c834f2fb46e4e2f27001 (diff)
downloadQt-547b43c7422559410f9dd8e410105ee97773f353.zip
Qt-547b43c7422559410f9dd8e410105ee97773f353.tar.gz
Qt-547b43c7422559410f9dd8e410105ee97773f353.tar.bz2
Improving clipboard integration
Derive a data accessor class from QMimeData so application level code can query MIME type availability through it or directly attempt to fetch data by MIME type even if the type is not yet known to QBBClipboard. Also make sure any MIME type used by the application in setMimeData operations is checked for availability when being queried for formats. This is a backport of 08cc2d27794e6bafb75cdc35b6966def35f9facb in master of Qt5 qtbase Change-Id: I86455cfb58e2e00ac3e992a8228ee7167f8d2a20 Reviewed-by: Sean Harmer <sh@theharmers.co.uk> Reviewed-by: Jørgen Lind <jorgen.lind@nokia.com>
-rw-r--r--src/plugins/platforms/blackberry/qbbclipboard.cpp193
-rw-r--r--src/plugins/platforms/blackberry/qbbclipboard.h8
2 files changed, 157 insertions, 44 deletions
diff --git a/src/plugins/platforms/blackberry/qbbclipboard.cpp b/src/plugins/platforms/blackberry/qbbclipboard.cpp
index 3f7d2d5..d540a98 100644
--- a/src/plugins/platforms/blackberry/qbbclipboard.cpp
+++ b/src/plugins/platforms/blackberry/qbbclipboard.cpp
@@ -42,25 +42,145 @@
#ifndef QT_NO_CLIPBOARD
#include "qbbclipboard.h"
-#include <QUrl>
-#include <QStringList>
-#include <QColor>
+
#include <QDebug>
+#include <QMimeData>
+#include <QStringList>
#include <clipboard/clipboard.h>
#include <errno.h>
QT_BEGIN_NAMESPACE
-static const char *typeList[] = {"text/html", "text/plain", "application/x-color"};
+
+// null terminated array
+static const char *typeList[] = {"text/html", "text/plain", "image/png", "image/jpeg", "application/x-color", 0};
+
+static QByteArray readClipboardBuff(const char *type)
+{
+ char *pbuffer;
+ if (is_clipboard_format_present(type) == 0) {
+ int size = get_clipboard_data(type, &pbuffer);
+ if (size != -1 && pbuffer) {
+ const QByteArray result = QByteArray(pbuffer, size);
+ free(pbuffer);
+ return result;
+ }
+ }
+
+ return QByteArray();
+}
+
+class QBBClipboard::MimeData : public QMimeData
+{
+ Q_OBJECT
+public:
+ MimeData(QBBClipboard *clipboard)
+ : QMimeData(),
+ m_clipboard(clipboard),
+ m_userMimeData(0)
+ {
+ Q_ASSERT(clipboard);
+
+ for (int i = 0; typeList[i] != 0; ++i) {
+ m_formatsToCheck << QString::fromUtf8(typeList[i]);
+ }
+ }
+
+ ~MimeData()
+ {
+ delete m_userMimeData;
+ }
+
+ void addFormatToCheck(const QString &format) {
+ m_formatsToCheck << format;
+
+#if defined(QBBCLIPBOARD_DEBUG)
+ qDebug() << Q_FUNC_INFO << "formats=" << m_formatsToCheck;
+#endif
+ }
+
+ bool hasFormat(const QString &mimetype) const
+ {
+ const bool result = is_clipboard_format_present(mimetype.toUtf8().constData()) == 0;
+#if defined(QBBCLIPBOARD_DEBUG)
+ qDebug() << Q_FUNC_INFO << "mimetype=" << mimetype << "result=" << result;
+#endif
+ return result;
+ }
+
+ QStringList formats() const
+ {
+ QStringList result;
+
+ Q_FOREACH (const QString &format, m_formatsToCheck) {
+ if (is_clipboard_format_present(format.toUtf8().constData()) == 0)
+ result << format;
+ }
+
+#if defined(QBBCLIPBOARD_DEBUG)
+ qDebug() << Q_FUNC_INFO << "result=" << result;
+#endif
+ return result;
+ }
+
+ void setUserMimeData(QMimeData *userMimeData)
+ {
+ delete m_userMimeData;
+ m_userMimeData = userMimeData;
+
+ // system clipboard API doesn't allow detection of changes by other applications
+ // simulate an owner change through delayed invocation
+ // basically transfer ownership of data to the system clipboard once event processing resumes
+ if (m_userMimeData)
+ QMetaObject::invokeMethod(this, "releaseOwnership", Qt::QueuedConnection);
+ }
+
+ QMimeData *userMimeData()
+ {
+ return m_userMimeData;
+ }
+
+protected:
+ QVariant retrieveData(const QString &mimetype, QVariant::Type preferredType) const
+ {
+#if defined(QBBCLIPBOARD_DEBUG)
+ qDebug() << Q_FUNC_INFO << "mimetype=" << mimetype << "preferredType=" << preferredType;
+#endif
+ if (is_clipboard_format_present(mimetype.toUtf8().constData()) != 0)
+ return QMimeData::retrieveData(mimetype, preferredType);
+
+ const QByteArray data = readClipboardBuff(mimetype.toUtf8().constData());
+ return qVariantFromValue(data);
+ }
+
+private Q_SLOTS:
+ void releaseOwnership()
+ {
+ if (m_userMimeData) {
+#if defined(QBBCLIPBOARD_DEBUG)
+ qDebug() << Q_FUNC_INFO << "user data formats=" << m_userMimeData->formats() << "system formats=" << formats();
+#endif
+ delete m_userMimeData;
+ m_userMimeData = 0;
+ m_clipboard->emitChanged(QClipboard::Clipboard);
+ }
+ }
+
+private:
+ QBBClipboard * const m_clipboard;
+
+ QSet<QString> m_formatsToCheck;
+ QMimeData *m_userMimeData;
+};
QBBClipboard::QBBClipboard()
+ : m_mimeData(new MimeData(this))
{
- mMimeData = 0;
}
QBBClipboard::~QBBClipboard()
{
- delete mMimeData;
+ delete m_mimeData;
}
void QBBClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode)
@@ -68,44 +188,37 @@ void QBBClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode)
if (mode != QClipboard::Clipboard)
return;
- if (mMimeData != data) {
- delete mMimeData;
- mMimeData = data;
- }
+ if (data == m_mimeData || data == m_mimeData->userMimeData())
+ return;
empty_clipboard();
+ m_mimeData->clear();
+ m_mimeData->setUserMimeData(data);
+
if (data == 0)
return;
- QStringList format = data->formats();
- for (int i = 0; i < format.size(); ++i) {
- QString type = format.at(i);
- QByteArray buf = data->data(type);
- if (!buf.size())
- continue;
-
- int ret = set_clipboard_data(type.toUtf8().data(), buf.size(), buf.data());
+ const QStringList formats = data->formats();
#if defined(QBBCLIPBOARD_DEBUG)
- qDebug() << "QBB: set " << type.toUtf8().data() << "to clipboard, size=" << buf.size() << ";ret=" << ret;
+ qDebug() << Q_FUNC_INFO << "formats=" << formats;
#endif
- }
-}
-void QBBClipboard::readClipboardBuff(const char *type)
-{
- char *pbuffer;
- if (is_clipboard_format_present(type) == 0) {
- int size = get_clipboard_data(type, &pbuffer);
- if (size != -1 && pbuffer) {
- QString qtype = type;
+ Q_FOREACH (const QString &format, formats) {
+ const QByteArray buf = data->data(format);
+
+ if (buf.isEmpty())
+ continue;
+
+ int ret = set_clipboard_data(format.toUtf8().data(), buf.size(), buf.data());
#if defined(QBBCLIPBOARD_DEBUG)
- qDebug() << "QBB: clipboard has " << qtype;
+ qDebug() << "QBB: set " << format << "to clipboard, size=" << buf.size() << ";ret=" << ret;
#endif
- mMimeData->setData(qtype, QByteArray(pbuffer, size));
- delete pbuffer;
- }
+ if (ret)
+ m_mimeData->addFormatToCheck(format);
}
+
+ emitChanged(QClipboard::Clipboard);
}
QMimeData* QBBClipboard::mimeData(QClipboard::Mode mode)
@@ -113,16 +226,16 @@ QMimeData* QBBClipboard::mimeData(QClipboard::Mode mode)
if (mode != QClipboard::Clipboard)
return 0;
- if (!mMimeData)
- mMimeData = new QMimeData();
-
- mMimeData->clear();
+ if (m_mimeData->userMimeData())
+ return m_mimeData->userMimeData();
- for (int i = 0; i < 3; i++)
- readClipboardBuff(typeList[i]);
+ m_mimeData->clear();
- return mMimeData;
+ return m_mimeData;
}
QT_END_NAMESPACE
-#endif //QT_NO_CLIPBOAR
+
+#include "qbbclipboard.moc"
+
+#endif //QT_NO_CLIPBOARD
diff --git a/src/plugins/platforms/blackberry/qbbclipboard.h b/src/plugins/platforms/blackberry/qbbclipboard.h
index 1241bf0..da4445b 100644
--- a/src/plugins/platforms/blackberry/qbbclipboard.h
+++ b/src/plugins/platforms/blackberry/qbbclipboard.h
@@ -42,7 +42,6 @@
#ifndef QT_NO_CLIPBOARD
#include <QtGui/QPlatformClipboard>
-#include <QMimeData>
QT_BEGIN_NAMESPACE
@@ -53,12 +52,13 @@ public:
virtual ~QBBClipboard();
virtual QMimeData *mimeData(QClipboard::Mode mode = QClipboard::Clipboard);
virtual void setMimeData(QMimeData *data, QClipboard::Mode mode = QClipboard::Clipboard);
+
private:
- QMimeData *mMimeData;
- void readClipboardBuff(const char *type);
+ class MimeData;
+ MimeData *m_mimeData;
};
QT_END_NAMESPACE
-#endif //QT_NO_CLIPBOAR
+#endif //QT_NO_CLIPBOARD
#endif //QBBCLIPBOARD_H