diff options
-rw-r--r-- | src/plugins/platforms/blackberry/qbbclipboard.cpp | 193 | ||||
-rw-r--r-- | src/plugins/platforms/blackberry/qbbclipboard.h | 8 |
2 files changed, 157 insertions, 44 deletions
diff --git a/src/plugins/platforms/blackberry/qbbclipboard.cpp b/src/plugins/platforms/blackberry/qbbclipboard.cpp index 3f7d2d5588..d540a980de 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 1241bf0442..da4445b7e3 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 |