Changeset 326 for trunk/src/gui


Ignore:
Timestamp:
Nov 19, 2009, 2:44:19 AM (16 years ago)
Author:
Dmitry A. Kuminov
Message:

gui/kernel: QClipboard: Added watching for the clipboard data changes and support for delayed data rendering.

Location:
trunk/src/gui/kernel
Files:
2 edited

Legend:

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

    r324 r326  
    9292    if (!WinOpenClipbrd(NULLHANDLE)) {
    9393#ifndef QT_NO_DEBUG
    94         qWarning("QClipboardWatcher: WinOpenClipbrd failed with 0x%lX",
    95                  WinGetLastError(NULLHANDLE));
     94        qWarning("QClipboardWatcher:
     95                 WinGetLastError(NULLHANDLE));
    9696#endif
    9797        return;
     
    168168    ~QClipboardData();
    169169
    170     void setSource(QMimeData *s)
     170    void setSource(QMimeData *s);
     171
     172    void setAsClipboardViewer();
     173    bool ownsClipboard();
     174    void renderAllFormats(bool isDelayed);
     175
     176    static QClipboardData *instance()
    171177    {
    172         if (s == src)
    173             return;
    174         delete src;
    175         src = s;
    176     }
    177 
    178     QMimeData *source()
     178        if (instancePtr == 0) {
     179            instancePtr = new QClipboardData;
     180        }
     181        Q_ASSERT(instancePtr);
     182        return instancePtr;
     183    }
     184
     185    static void deleteInstance()
    179186    {
    180         return src;
    181     }
    182 
     187        delete instancePtr;
     188        instancePtr = 0;
     189    }
     190
     191private:
     192    bool openClipboard();
     193    void closeClipboard();
    183194    bool setClipboard(QPMMime *converter, ULONG format, bool isDelayed);
     195
    184196
    185197    MRESULT message(ULONG msg, MPARAM mp1, MPARAM mp2);
    186198
    187 private:
    188199    QMimeData *src;
     200
     201
     202
     203
     204
     205
    189206};
    190207
    191 QClipboardData::QClipboardData() : src(0)
     208// static
     209QClipboardData *QClipboardData::instancePtr = 0;
     210
     211QClipboardData::QClipboardData()
     212    : src(0), prevClipboardViewer(NULLHANDLE)
     213    , ignore_WM_DESTROYCLIPBOARD(false)
    192214{
    193215}
     
    195217QClipboardData::~QClipboardData()
    196218{
     219
     220
     221
     222
     223
     224
     225
     226
     227
     228
     229
     230
    197231    delete src;
     232
     233
     234
     235
     236
     237
     238
     239
     240
     241
     242
     243
     244
     245
     246
     247
     248
     249
     250
     251
     252
     253
     254
     255
     256
     257
     258
     259
     260
     261
     262
     263
     264
     265
     266
     267
     268
     269
     270
     271
     272
     273
     274
    198275}
    199276
     
    223300#ifdef QCLIPBOARD_DEBUG
    224301    qDebug("QClipboardData::setClipboard: convert to CF 0x%lX, flags 0x%lX,"
    225            "data 0x%lX, ok %d", format, flags, data, ok);
     302           "data 0x%lX, , ok);
    226303#endif
    227304
     
    229306}
    230307
     308
     309
     310
     311
     312
     313
     314
     315
     316
     317
     318
     319
     320
     321
     322
     323
     324
     325
     326
     327
     328
     329
     330
     331
     332
     333
     334
     335
     336
     337
     338
     339
     340
     341
     342
     343
     344
     345
     346
     347
     348
     349
     350
     351
     352
     353
     354
     355
     356
     357
     358
     359
     360
     361
     362
    231363MRESULT QClipboardData::message(ULONG msg, MPARAM mp1, MPARAM mp2)
    232364{
    233     return 0;
    234 }
    235 
    236 static QClipboardData *ptrClipboardData = 0;
    237 
    238 static QClipboardData *clipboardData()
    239 {
    240     if (ptrClipboardData == 0) {
    241         ptrClipboardData = new QClipboardData;
    242     }
    243     return ptrClipboardData;
    244 }
    245 
    246 static void cleanupClipboardData()
    247 {
    248     delete ptrClipboardData;
    249     ptrClipboardData = 0;
     365#ifdef QCLIPBOARD_DEBUG
     366    qDebug("QClipboardData::message: msg %08lX, mp1 %p, mp2 %p",
     367           msg, mp1, mp2);
     368#endif
     369
     370    switch (msg) {
     371
     372        case WM_DRAWCLIPBOARD: {
     373            // ask QClipboard to emit changed() signals
     374            QClipboardEvent e(reinterpret_cast<QEventPrivate *>(1));
     375            qt_sendSpontaneousEvent(QApplication::clipboard(), &e);
     376
     377            if (hwnd() != WinQueryClipbrdOwner(NULLHANDLE) && src) {
     378                // we no longer the clipboard, clean up the clipboard object
     379                setSource(0);
     380            }
     381            // PM doesn't inform the previous clipboard viewer if another
     382            // app changes it (nor does it support viewer chains in some other
     383            // way). The best we can do is to propagate the message to the
     384            // previous clipboard viewer ourselves (though there is no guarantee
     385            // that all non-Qt apps will do the same).
     386            if (prevClipboardViewer) {
     387                // propagate the message to the previous clipboard viewer
     388                BOOL ok = WinPostMsg(prevClipboardViewer, msg, mp1, mp2);
     389                if (!ok)
     390                    prevClipboardViewer = NULLHANDLE;
     391            }
     392            break;
     393        }
     394
     395        case WM_DESTROYCLIPBOARD:
     396            if (!ignore_WM_DESTROYCLIPBOARD)
     397                setSource(0);
     398            break;
     399
     400        case WM_RENDERFMT:
     401            renderFormat((ULONG)mp1);
     402            break;
     403
     404        case WM_RENDERALLFMTS:
     405            renderAllFormats(false);
     406            break;
     407
     408        default:
     409            break;
     410    }
     411
     412    return (MRESULT)TRUE;
    250413}
    251414
    252415////////////////////////////////////////////////////////////////////////////////
    253416
    254 static bool ignore_WM_DESTROYCLIPBOARD = FALSE;
    255 
    256417QClipboard::~QClipboard()
    257418{
    258     cleanupClipboardData();
     419    ();
    259420}
    260421
    261422void QClipboard::setMimeData(QMimeData *src, Mode mode)
    262423{
     424
     425
     426
     427
    263428    if (mode != Clipboard) {
    264429        delete src;
     
    266431    }
    267432
    268     if (!WinOpenClipbrd(NULLHANDLE)) {
    269 #ifndef QT_NO_DEBUG
    270         qWarning("QClipboard::setMimeData: WinOpenClipbrd failed with 0x%lX",
    271                  WinGetLastError(NULLHANDLE));
    272 #endif
    273         delete src;
    274         return;
    275     }
    276 
    277     QClipboardData *d = clipboardData();
     433    QClipboardData *d = QClipboardData::instance();
    278434    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
    290435
    291436    if (!src)
     
    295440                         QCoreApplication::instance()->d_func()->in_exec;
    296441
    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     }
    307 
    308     WinCloseClipbrd(NULLHANDLE);
     442    d->renderAllFormats(runsEventLoop);
    309443}
    310444
    311445void QClipboard::clear(Mode mode)
    312446{
    313     // @todo implement
     447   
    314448}
    315449
    316450bool QClipboard::event(QEvent *e)
    317451{
    318     // @todo implement
    319     return false;
     452    if (e->type() != QEvent::Clipboard)
     453        return QObject::event(e);
     454
     455    if (!((QClipboardEvent*)e)->data()) {
     456        // this is sent by QApplication to render all formats at app shut down
     457        QClipboardData::instance()->renderAllFormats(false);
     458    } else {
     459        // this is sent by QClipboardData to notify about clipboard data change
     460        emitChanged(QClipboard::Clipboard);
     461    }
     462
     463    return true;
    320464}
    321465
    322466void QClipboard::connectNotify(const char *signal)
    323467{
    324     // @todo implement
     468    if (qstrcmp(signal, SIGNAL(dataChanged())) == 0) {
     469        // ensure we are up and running (by instantiating QClipboardData and
     470        // setting it as the clipboard viewer to receive notifications on
     471        // clipboard contents chages) but block signals so the dataChange signal
     472        // is not emitted while being connected to.
     473        bool blocked = blockSignals(true);
     474        QClipboardData::instance()->setAsClipboardViewer();
     475        blockSignals(blocked);
     476    }
    325477}
    326478
     
    338490bool QClipboard::ownsMode(Mode mode) const
    339491{
    340     // @todo implement
     492    if (mode == Clipboard) {
     493        return QClipboardData::instance()->ownsClipboard();
     494    }
    341495    return false;
    342496}
     
    344498void QClipboard::ownerDestroyed()
    345499{
     500
    346501}
    347502
  • trunk/src/gui/kernel/qmime.h

    r324 r326  
    137137private:
    138138    friend class QClipboardWatcher;
     139
    139140    friend class QClipboard;
    140141
Note: See TracChangeset for help on using the changeset viewer.