Changeset 334


Ignore:
Timestamp:
Nov 20, 2009, 7:39:03 PM (16 years ago)
Author:
Dmitry A. Kuminov
Message:

gui/kernel: mime: Implemented mime<-clipboard interface for "text/plain" (getting from the system clipboard).

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

Legend:

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

    r331 r334  
    7474{
    7575public:
    76     QClipboardWatcher() : isDirty(true) {}
     76    QClipboardWatcher() {}
    7777
    7878    bool hasFormat_sys(const QString &mimetype) const;
     
    8282private:
    8383
    84     void peekData() const;
     84    ) const;
    8585
    8686    mutable QList<ULONG> formats;
    8787    mutable QList<QPMMime::Match> matches;
    88     mutable bool isDirty;
    8988};
    9089
    91 void QClipboardWatcher::peekData() const
    92 {
    93     if (!isDirty)
    94         return;
    95 
     90bool QClipboardWatcher::peekData(bool leaveOpen) const
     91{
    9692    if (!WinOpenClipbrd(NULLHANDLE)) {
    9793#ifndef QT_NO_DEBUG
     
    9995                 "failed with 0x%lX", WinGetLastError(NULLHANDLE));
    10096#endif
    101         return;
    102     }
    103 
    104     formats.clear();
     97        return;
     98    }
     99
     100    ;
    105101    ULONG cf = 0;
    106102    while ((cf = WinEnumClipbrdFmts(NULLHANDLE, cf)))
    107         formats << cf;
    108 
    109     WinCloseClipbrd(NULLHANDLE);
    110 
     103        newFormats << cf;
     104
     105    if (!leaveOpen)
     106        WinCloseClipbrd(NULLHANDLE);
     107
     108    // optimization: we don't want to call the potentially expensive
     109    // allConvertersFromFormats() unlesss we really got a different set
     110    if (newFormats == formats)
     111        return true;
     112
     113    formats = newFormats;
    111114    matches = QPMMime::allConvertersFromFormats(formats);
    112     isDirty = false;
     115
     116#ifdef QCLIPBOARD_DEBUG
     117    foreach(QPMMime::Match match, matches)
     118        DEBUG(("QClipboardWatcher::peekData: converter %p mime \"%ls\" "
     119               "format 0x%lX priority %d", match.converter, match.mime.utf16(),
     120               match.format, match.priority));
     121#endif
     122
     123    return true;
    113124}
    114125
    115126bool QClipboardWatcher::hasFormat_sys(const QString &mime) const
    116127{
    117     peekData();
    118     if (isDirty)
    119         return false; // peekData() failed
     128    if (!peekData())
     129        return false;
    120130
    121131    foreach (QPMMime::Match match, matches)
     
    130140    QStringList fmts;
    131141
    132     peekData();
    133     if (isDirty)
    134         return fmts; // peekData() failed
     142    if (!peekData())
     143        return fmts;
    135144
    136145    foreach (QPMMime::Match match, matches)
     
    145154    QVariant result;
    146155
    147     peekData();
    148     if (isDirty)
    149         return result; // peekData() failed
     156    if (!peekData(true /*leaveOpen*/))
     157        return result;
    150158
    151159    foreach (QPMMime::Match match, matches) {
     
    157165                                                            data, match.mime, type);
    158166            }
    159             return result;
    160         }
    161     }
     167            break;
     168        }
     169    }
     170
     171    WinCloseClipbrd(NULLHANDLE);
    162172
    163173    return result;
     
    175185
    176186    void setAsClipboardViewer();
    177     bool ownsClipboard();
     187    bool ownsClipboard();
    178188    void putAllMimeToClipboard(bool isDelayed);
    179189    void flushClipboard();
     190
     191
    180192
    181193    static QClipboardData *instance()
     
    202214    QList<QPMMime::Match> matches;
    203215    HWND prevClipboardViewer;
     216
     217
    204218
    205219    bool ignore_WM_DESTROYCLIPBOARD;
     
    265279}
    266280
    267 bool QClipboardData::ownsClipboard()
     281bool QClipboardData::ownsClipboard()
    268282{
    269283    return src && hwnd() == WinQueryClipbrdOwner(NULLHANDLE);
     
    346360        setSource(0);
    347361    }
     362
     363
     364
     365
     366
     367
     368
     369
    348370}
    349371
     
    481503const QMimeData *QClipboard::mimeData(Mode mode) const
    482504{
    483     // @todo implement
    484     return 0;
     505    if (mode != Clipboard)
     506        return 0;
     507
     508    return QClipboardData::instance()->mimeData();
    485509}
    486510
  • trunk/src/gui/kernel/qmime.h

    r332 r334  
    127127                                     ULONG &flags, ULONG *data) const = 0;
    128128
     129
     130
    129131    // for converting to Qt
    130     virtual QStringList mimesForFormats(const QList<ULONG> &formats) const = 0;
     132    virtual Q mimesForFormats(const QList<ULONG> &formats) const = 0;
    131133    virtual QVariant convertFromFormat(ULONG format, ULONG flags, ULONG data,
    132134                                       const QString &mimeType,
     
    145147    struct Match
    146148    {
    147         Match(QPMMime *c, const QString f, int p) :
    148             converter(c), mime(f), format(0), priority(p) {}
     149        Match(QPMMime *c, const QString f, int p) :
     150            converter(c), mime(f), format(), priority(p) {}
    149151
    150152        Match(QPMMime *c, ULONG f, int p) :
     
    153155        QPMMime *converter;
    154156        QString mime; // used by allConvertersFromFormats()
    155         ULONG format; // used by allConvertersFromMimeData()
     157        ULONG format; // used by allConvertersFromMimeData()
    156158        int priority;
    157159    };
  • trunk/src/gui/kernel/qmime_pm.cpp

    r332 r334  
    246246
    247247/*!
    248     \fn QStringList QPMMime::mimesForFormats(const QList<ULONG> &formats) const
     248    \fn Q QPMMime::mimesForFormats(const QList<ULONG> &formats) const
    249249
    250250    Returns a list of mime types that will be created form the specified \a list
    251251    of \a formats, in order of precedence (the most suitable mime type comes
    252252    first), or an empty list if neither of the \a formats is supported by this
    253     converter.
     253    converter. Note that each pair in the returned list consists of the mime
     254    type name and the corresponding format identifier.
    254255
    255256    All subclasses must reimplement this pure virtual function.
     
    276277    QList<QPMMime*> mimes = theMimeList()->mimes();
    277278    for (int i = mimes.size()-1; i >= 0; --i) {
    278         QStringList fmts = mimes[i]->mimesForFormats(formats);
     279        Q fmts = mimes[i]->mimesForFormats(formats);
    279280        int priority = 0;
    280         foreach (QString fmt, fmts) {
     281        foreach ( fmt, fmts) {
    281282            ++priority;
    282283            QList<Match>::iterator it = matches.begin();
    283284            for (; it != matches.end(); ++it) {
    284285                Match &match = *it;
    285                 if (match.mime == fmt) {
     286                if (match.mime == fmt) {
    286287                    // replace if priority is higher, ignore otherwise
    287288                    if (priority < match.priority) {
    288289                        match.converter = mimes[i];
     290
    289291                        match.priority = priority;
    290292                    }
     
    293295            }
    294296            if (it == matches.end()) {
    295                 matches += Match(mimes[i], fmt, priority);
     297                matches += Match(mimes[i], fmt, priority);
    296298            }
    297299        }
     
    344346                             ULONG &flags, ULONG *data) const;
    345347
    346     QStringList mimesForFormats(const QList<ULONG> &formats) const;
     348    Q mimesForFormats(const QList<ULONG> &formats) const;
    347349    QVariant convertFromFormat(ULONG format, ULONG flags, ULONG data,
    348350                               const QString &mimeType,
     
    388390        int maxsize = str.size()+str.size()/40+3;
    389391        r.fill('\0', maxsize);
    390         char* o = r.data();
    391         const char* d = str.data();
     392        charo = r.data();
     393        const chard = str.data();
    392394        const int s = str.size();
    393395        bool cr = false;
     
    454456}
    455457
    456 QStringList QPMMimeText::mimesForFormats(const QList<ULONG> &formats) const
    457 {
    458     QStringList mimes;
     458Q QPMMimeText::mimesForFormats(const QList<ULONG> &formats) const
     459{
     460    Q mimes;
    459461    foreach(ULONG cf, formats) {
    460         if (cf == CF_TEXT || cf == CF_TextUnicode){
    461             mimes << QLatin1String("text/plain");
    462             break;
    463         }
     462        // prefer unicode over local8Bit
     463        if (cf == CF_TextUnicode)
     464            mimes.prepend(qMakePair(QString(QLatin1String("text/plain")), cf));
     465        if (cf == CF_TEXT)
     466            mimes.append(qMakePair(QString(QLatin1String("text/plain")), cf));
    464467    }
    465468    return mimes;
     
    470473                                        QVariant::Type preferredType) const
    471474{
    472     return QVariant();
     475    QVariant ret;
     476
     477    // @todo why is it startsWith? the rest of the mime specification (encoding,
     478    // etc) isn't taken into account... Anyway, copied the logic from Windows.
     479    if (!mimeType.startsWith("text/plain"))
     480        return ret;
     481    if (!(flags & CFI_POINTER) || !data)
     482        return ret;
     483
     484    QString str;
     485
     486    if (format == CF_TEXT) {
     487        const char *d = (const char *)data;
     488        QByteArray r("");
     489        if (*d) {
     490            const int s = qstrlen(d);
     491            r.fill('\0', s);
     492            char *o = r.data();
     493            int j = 0;
     494            for (int i = 0; i < s; i++) {
     495                char c = d[i];
     496                if (c != '\r')
     497                    o[j++] = c;
     498            }
     499        }
     500        str = QString::fromLocal8Bit(r);
     501    } else if (format == CF_TextUnicode) {
     502        str = QString::fromUtf16((const unsigned short *)data);
     503        str.replace(QLatin1String("\r\n"), QLatin1String("\n"));
     504    }
     505
     506    if (preferredType == QVariant::String)
     507        ret = str;
     508    else
     509        ret = str.toUtf8();
     510
     511    return ret;
    473512}
    474513
Note: See TracChangeset for help on using the changeset viewer.