Ignore:
Timestamp:
Nov 18, 2009, 1:49:31 AM (16 years ago)
Author:
Dmitry A. Kuminov
Message:

gui/kernel: Improved mime <-> PM clipboard format conversion interfaces.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/gui/kernel/qclipboard_pm.cpp

    r323 r324  
    5252#include "qevent.h"
    5353#include "qmime.h"
     54#include "qdnd_p.h"
     55
    5456#include "qt_os2.h"
    55 #include "qdnd_p.h"
     57#include "private/qpmobjectwindow_pm_p.h"
    5658
    5759#define QCLIPBOARD_DEBUG
    5860
     61#ifdef QCLIPBOARD_DEBUG
     62#include "qdebug.h"
     63#endif
     64
    5965QT_BEGIN_NAMESPACE
    6066
     
    6470{
    6571public:
    66     QClipboardWatcher() {}
     72    QClipboardWatcher() : isDirty(true) {}
    6773
    6874    bool hasFormat_sys(const QString &mimetype) const;
    6975    QStringList formats_sys() const;
    7076    QVariant retrieveData_sys(const QString &mimetype, QVariant::Type preferredType) const;
     77
     78private:
     79
     80    void peekData() const;
     81
     82    mutable QList<ULONG> formats;
     83    mutable QList<QPMMime::Match> matches;
     84    mutable bool isDirty;
    7185};
    7286
     87void QClipboardWatcher::peekData() const
     88{
     89    if (!isDirty)
     90        return;
     91
     92    if (!WinOpenClipbrd(NULLHANDLE)) {
     93#ifndef QT_NO_DEBUG
     94        qWarning("QClipboardWatcher: WinOpenClipbrd failed with 0x%lX",
     95                 WinGetLastError(NULLHANDLE));
     96#endif
     97        return;
     98    }
     99
     100    formats.clear();
     101    ULONG cf = 0;
     102    while ((cf = WinEnumClipbrdFmts(NULLHANDLE, cf)))
     103        formats << cf;
     104
     105    WinCloseClipbrd(NULLHANDLE);
     106
     107    matches = QPMMime::allConvertersFromFormats(formats);
     108    isDirty = false;
     109}
     110
    73111bool QClipboardWatcher::hasFormat_sys(const QString &mime) const
    74112{
    75     bool ok = false;
    76     if (WinOpenClipbrd(NULLHANDLE)) {
    77         ULONG cf = 0;
    78         while ((cf = WinEnumClipbrdFmts(NULLHANDLE, cf))) {
    79             if (QPMMime::converterToMime(mime, cf)) {
    80                 ok = true;
    81                 break;
    82             }
    83         }
    84         WinCloseClipbrd(NULLHANDLE);
    85     }
    86 #ifndef QT_NO_DEBUG
    87     else
    88         qWarning("QClipboardWatcher: WinOpenClipbrd failed with %lX",
    89                  WinGetLastError(NULLHANDLE));
    90 #endif
    91     return ok;
     113    peekData();
     114    if (isDirty)
     115        return false; // peekData() failed
     116
     117    foreach (QPMMime::Match match, matches)
     118        if (match.mime == mime)
     119            return true;
     120
     121    return false;
    92122}
    93123
     
    95125{
    96126    QStringList fmts;
    97     if (WinOpenClipbrd(NULLHANDLE)) {
    98         QVector<ULONG> cfs;
    99         ULONG cf = 0;
    100         while ((cf = WinEnumClipbrdFmts(NULLHANDLE, cf)))
    101             cfs << cf;
    102         fmts = QPMMime::allMimesForFormats(cfs);
    103         WinCloseClipbrd(NULLHANDLE);
    104     }
    105 #ifndef QT_NO_DEBUG
    106     else
    107         qWarning("QClipboardWatcher: WinOpenClipbrd failed with %lX",
    108                  WinGetLastError(NULLHANDLE));
    109 #endif
     127
     128    peekData();
     129    if (isDirty)
     130        return fmts; // peekData() failed
     131
     132    foreach (QPMMime::Match match, matches)
     133        fmts << match.mime;
     134
    110135    return fmts;
    111136}
     
    116141    QVariant result;
    117142
    118     if (WinOpenClipbrd(NULLHANDLE)) {
    119         ULONG cf = 0;
    120         while ((cf = WinEnumClipbrdFmts(NULLHANDLE, cf))) {
    121             QPMMime *converter = QPMMime::converterToMime(mime, cf);
    122             if (converter) {
    123                 ULONG flags;
    124                 if (WinQueryClipbrdFmtInfo(NULLHANDLE, cf, &flags)) {
    125                     ULONG data = WinQueryClipbrdData(NULLHANDLE, cf);
    126                     if (data) {
    127                         result = converter->convertToMime(mime, type, cf, flags, data);
    128                     }
    129                 }
    130                 break;
     143    peekData();
     144    if (isDirty)
     145        return result; // peekData() failed
     146
     147    foreach (QPMMime::Match match, matches) {
     148        if (match.mime == mime) {
     149            ULONG flags;
     150            if (WinQueryClipbrdFmtInfo(NULLHANDLE, match.format, &flags)) {
     151                ULONG data = WinQueryClipbrdData(NULLHANDLE, match.format);
     152                result = match.converter->convertFromFormat(match.format, flags,
     153                                                            data, match.mime, type);
    131154            }
     155            return result;
    132156        }
    133         WinCloseClipbrd(NULLHANDLE);
    134     }
    135 #ifndef QT_NO_DEBUG
    136     else
    137         qWarning("QClipboardWatcher: WinOpenClipbrd failed with %lX",
    138                  WinGetLastError(NULLHANDLE));
    139 #endif
     157    }
     158
    140159    return result;
    141160}
     
    143162////////////////////////////////////////////////////////////////////////////////
    144163
    145 class QClipboardData
     164class QClipboardData : public QPMObjectWindow
    146165{
    147166public:
     
    149168    ~QClipboardData();
    150169
    151     // @todo ...
     170    void setSource(QMimeData *s)
     171    {
     172        if (s == src)
     173            return;
     174        delete src;
     175        src = s;
     176    }
     177
     178    QMimeData *source()
     179    {
     180        return src;
     181    }
     182
     183    bool setClipboard(QPMMime *converter, ULONG format, bool isDelayed);
     184
     185    MRESULT message(ULONG msg, MPARAM mp1, MPARAM mp2);
    152186
    153187private:
     188    QMimeData *src;
    154189};
    155190
    156 QClipboardData::QClipboardData()
     191QClipboardData::QClipboardData() : src(0)
    157192{
    158193}
     
    160195QClipboardData::~QClipboardData()
    161196{
     197    delete src;
     198}
     199
     200bool QClipboardData::setClipboard(QPMMime *converter, ULONG format,
     201                                  bool isDelayed)
     202{
     203    Q_ASSERT(src);
     204    if (!src)
     205        return false;
     206
     207    bool ok;
     208    ULONG flags = 0, data = 0;
     209
     210    if (isDelayed) {
     211        // setup delayed rendering of clipboard data
     212        ok = converter->convertFromMimeData(src, format, flags, 0);
     213        if (ok) {
     214            WinSetClipbrdOwner(NULLHANDLE, hwnd());
     215            WinSetClipbrdData(NULLHANDLE, 0, format, flags);
     216        }
     217    } else {
     218        // render now
     219        ok = converter->convertFromMimeData(src, format, flags, &data);
     220        if (ok)
     221            WinSetClipbrdData(NULLHANDLE, data, format, flags);
     222    }
     223#ifdef QCLIPBOARD_DEBUG
     224    qDebug("QClipboardData::setClipboard: convert to CF 0x%lX, flags 0x%lX,"
     225           "data 0x%lX, ok %d", format, flags, data, ok);
     226#endif
     227
     228    return ok;
     229}
     230
     231MRESULT QClipboardData::message(ULONG msg, MPARAM mp1, MPARAM mp2)
     232{
     233    return 0;
    162234}
    163235
     
    168240    if (ptrClipboardData == 0) {
    169241        ptrClipboardData = new QClipboardData;
    170         // @todo ...
    171242    }
    172243    return ptrClipboardData;
     
    181252////////////////////////////////////////////////////////////////////////////////
    182253
     254static bool ignore_WM_DESTROYCLIPBOARD = FALSE;
     255
    183256QClipboard::~QClipboard()
    184257{
     
    188261void QClipboard::setMimeData(QMimeData *src, Mode mode)
    189262{
    190     if (mode != Clipboard)
     263    if (mode != Clipboard) {
     264        delete src;
    191265        return;
     266    }
    192267
    193268    if (!WinOpenClipbrd(NULLHANDLE)) {
    194269#ifndef QT_NO_DEBUG
    195         qWarning("QClipboard: WinOpenClipbrd failed with %lX",
     270        qWarning("QClipboard::setMimeData: WinOpenClipbrd failed with 0x%lX",
    196271                 WinGetLastError(NULLHANDLE));
    197272#endif
     273        delete src;
    198274        return;
    199275    }
    200276
    201     // @todo
    202 //  QClipboardData *d = clipboardData();
    203 //  d->setSource(src);
     277    QClipboardData *d = clipboardData();
     278    d->setSource(src);
     279
     280    ignore_WM_DESTROYCLIPBOARD = TRUE;
     281    BOOL ok = WinEmptyClipbrd(NULLHANDLE);
     282    ignore_WM_DESTROYCLIPBOARD = FALSE;
     283#ifndef QT_NO_DEBUG
     284    if (!ok)
     285        qWarning("QClipboard::setMimeData: WinEmptyClipbrd failed with 0x%lX",
     286                 WinGetLastError(NULLHANDLE));
     287#else
     288    Q_UNUSED(ok);
     289#endif
     290
     291    if (!src)
     292        return; // nothing to do
     293
     294    bool runsEventLoop = QCoreApplication::instance() &&
     295                         QCoreApplication::instance()->d_func()->in_exec;
     296
     297    QStringList formats = src->formats();
     298    foreach(QString mime, formats) {
     299#ifdef QCLIPBOARD_DEBUG
     300        qDebug() << "QClipboard::setMimeData: src mime" << mime;
     301#endif
     302        QList<QPMMime::Match> matches = QPMMime::allConvertersFromMimeData(src);
     303        foreach(QPMMime::Match match, matches) {
     304            d->setClipboard(match.converter, match.format, !runsEventLoop);
     305        }
     306    }
    204307
    205308    WinCloseClipbrd(NULLHANDLE);
Note: See TracChangeset for help on using the changeset viewer.