diff options
Diffstat (limited to 'src/platformsupport')
4 files changed, 136 insertions, 29 deletions
diff --git a/src/platformsupport/clipboard/qmacmime.mm b/src/platformsupport/clipboard/qmacmime.mm index 93d897503b..27a490335b 100644 --- a/src/platformsupport/clipboard/qmacmime.mm +++ b/src/platformsupport/clipboard/qmacmime.mm @@ -39,6 +39,13 @@ ** ****************************************************************************/ +#include <QtCore/qsystemdetection.h> +#if defined(Q_OS_IOS) +#import <UIKit/UIKit.h> +#elif defined(Q_OS_OSX) +#import <Cocoa/Cocoa.h> +#endif + #include "qmacmime_p.h" #include "qguiapplication.h" @@ -115,6 +122,7 @@ const QStringList& qt_mac_enabledDraggedTypes() \list \i public.utf8-plain-text - converts to "text/plain" \i public.utf16-plain-text - converts to "text/plain" + \i public.text - converts to "text/plain" \i public.html - converts to "text/html" \i public.url - converts to "text/uri-list" \i public.file-url - converts to "text/uri-list" @@ -282,9 +290,9 @@ QList<QByteArray> QMacPasteboardMimeTypeName::convertFromMime(const QString &, Q return ret; } -class QMacPasteboardMimePlainText : public QMacInternalPasteboardMime { +class QMacPasteboardMimePlainTextFallback : public QMacInternalPasteboardMime { public: - QMacPasteboardMimePlainText() : QMacInternalPasteboardMime(MIME_ALL) { } + QMacPasteboardMimePlainTextFallback() : QMacInternalPasteboardMime(MIME_ALL) { } QString convertorName(); QString flavorFor(const QString &mime); @@ -294,52 +302,54 @@ public: QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav); }; -QString QMacPasteboardMimePlainText::convertorName() +QString QMacPasteboardMimePlainTextFallback::convertorName() { - return QLatin1String("PlainText"); + return QLatin1String("PlainText (public.text)"); } -QString QMacPasteboardMimePlainText::flavorFor(const QString &mime) +QString QMacPasteboardMimePlainTextFallback::flavorFor(const QString &mime) { if (mime == QLatin1String("text/plain")) - return QLatin1String("com.apple.traditional-mac-plain-text"); + return QLatin1String("public.text"); return QString(); } -QString QMacPasteboardMimePlainText::mimeFor(QString flav) +QString QMacPasteboardMimePlainTextFallback::mimeFor(QString flav) { - if (flav == QLatin1String("com.apple.traditional-mac-plain-text")) + if (flav == QLatin1String("public.text")) return QLatin1String("text/plain"); return QString(); } -bool QMacPasteboardMimePlainText::canConvert(const QString &mime, QString flav) +bool QMacPasteboardMimePlainTextFallback::canConvert(const QString &mime, QString flav) { - return flavorFor(mime) == flav; + return mime == mimeFor(flav); } -QVariant QMacPasteboardMimePlainText::convertToMime(const QString &mimetype, QList<QByteArray> data, QString flavor) +QVariant QMacPasteboardMimePlainTextFallback::convertToMime(const QString &mimetype, QList<QByteArray> data, QString flavor) { if (data.count() > 1) - qWarning("QMacPasteboardMimePlainText: Cannot handle multiple member data"); - const QByteArray &firstData = data.first(); - QVariant ret; - if (flavor == QLatin1String("com.apple.traditional-mac-plain-text")) { + qWarning("QMacPasteboardMimePlainTextFallback: Cannot handle multiple member data"); + + if (flavor == QLatin1String("public.text")) { + // Note that public.text is documented by Apple to have an undefined encoding. From + // testing it seems that utf8 is normally used, at least by Safari on iOS. + const QByteArray &firstData = data.first(); return QString::fromCFString(CFStringCreateWithBytes(kCFAllocatorDefault, reinterpret_cast<const UInt8 *>(firstData.constData()), - firstData.size(), CFStringGetSystemEncoding(), false)); + firstData.size(), kCFStringEncodingUTF8, false)); } else { qWarning("QMime::convertToMime: unhandled mimetype: %s", qPrintable(mimetype)); } - return ret; + return QVariant(); } -QList<QByteArray> QMacPasteboardMimePlainText::convertFromMime(const QString &, QVariant data, QString flavor) +QList<QByteArray> QMacPasteboardMimePlainTextFallback::convertFromMime(const QString &, QVariant data, QString flavor) { QList<QByteArray> ret; QString string = data.toString(); - if (flavor == QLatin1String("com.apple.traditional-mac-plain-text")) - ret.append(string.toLatin1()); + if (flavor == QLatin1String("public.text")) + ret.append(string.toUtf8()); return ret; } @@ -477,6 +487,86 @@ QList<QByteArray> QMacPasteboardMimeHTMLText::convertFromMime(const QString &mim return ret; } +class QMacPasteboardMimeRtfText : public QMacInternalPasteboardMime { +public: + QMacPasteboardMimeRtfText() : QMacInternalPasteboardMime(MIME_ALL) { } + QString convertorName(); + + QString flavorFor(const QString &mime); + QString mimeFor(QString flav); + bool canConvert(const QString &mime, QString flav); + QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav); + QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav); +}; + +QString QMacPasteboardMimeRtfText::convertorName() +{ + return QLatin1String("Rtf"); +} + +QString QMacPasteboardMimeRtfText::flavorFor(const QString &mime) +{ + if (mime == QLatin1String("text/html")) + return QLatin1String("public.rtf"); + return QString(); +} + +QString QMacPasteboardMimeRtfText::mimeFor(QString flav) +{ + if (flav == QLatin1String("public.rtf")) + return QLatin1String("text/html"); + return QString(); +} + +bool QMacPasteboardMimeRtfText::canConvert(const QString &mime, QString flav) +{ +#if defined(Q_OS_IOS) + if (QSysInfo::MacintoshVersion < QSysInfo::MV_IOS_7_0) + return false; +#endif + + return mime == mimeFor(flav); +} + +QVariant QMacPasteboardMimeRtfText::convertToMime(const QString &mimeType, QList<QByteArray> data, QString flavor) +{ + if (!canConvert(mimeType, flavor)) + return QVariant(); + if (data.count() > 1) + qWarning("QMacPasteboardMimeHTMLText: Cannot handle multiple member data"); + + // Read RTF into to NSAttributedString, then convert the string to HTML + NSAttributedString *string = [[NSAttributedString alloc] initWithData:data.at(0).toNSData() + options:[NSDictionary dictionaryWithObject:NSRTFTextDocumentType forKey:NSDocumentTypeDocumentAttribute] + documentAttributes:nil + error:nil]; + + NSError *error; + NSRange range = NSMakeRange(0, [string length]); + NSDictionary *dict = [NSDictionary dictionaryWithObject:NSHTMLTextDocumentType forKey:NSDocumentTypeDocumentAttribute]; + NSData *htmlData = [string dataFromRange:range documentAttributes:dict error:&error]; + return QByteArray::fromNSData(htmlData); +} + +QList<QByteArray> QMacPasteboardMimeRtfText::convertFromMime(const QString &mime, QVariant data, QString flavor) +{ + QList<QByteArray> ret; + if (!canConvert(mime, flavor)) + return ret; + + NSAttributedString *string = [[NSAttributedString alloc] initWithData:data.toByteArray().toNSData() + options:[NSDictionary dictionaryWithObject:NSHTMLTextDocumentType forKey:NSDocumentTypeDocumentAttribute] + documentAttributes:nil + error:nil]; + + NSError *error; + NSRange range = NSMakeRange(0, [string length]); + NSDictionary *dict = [NSDictionary dictionaryWithObject:NSRTFTextDocumentType forKey:NSDocumentTypeDocumentAttribute]; + NSData *rtfData = [string dataFromRange:range documentAttributes:dict error:&error]; + ret << QByteArray::fromNSData(rtfData); + return ret; +} + class QMacPasteboardMimeFileUri : public QMacInternalPasteboardMime { public: QMacPasteboardMimeFileUri() : QMacInternalPasteboardMime(MIME_ALL) { } @@ -696,8 +786,9 @@ void QMacInternalPasteboardMime::initializeMimeTypes() new QMacPasteboardMimeAny; //standard types that we wrap + new QMacPasteboardMimePlainTextFallback; new QMacPasteboardMimeUnicodeText; - new QMacPasteboardMimePlainText; + new QMacPasteboardMimeRtfText; new QMacPasteboardMimeHTMLText; new QMacPasteboardMimeFileUri; new QMacPasteboardMimeUrl; diff --git a/src/platformsupport/eglconvenience/qeglplatformcursor.cpp b/src/platformsupport/eglconvenience/qeglplatformcursor.cpp index e99581183e..b6293e60ec 100644 --- a/src/platformsupport/eglconvenience/qeglplatformcursor.cpp +++ b/src/platformsupport/eglconvenience/qeglplatformcursor.cpp @@ -171,7 +171,7 @@ void QEGLPlatformCursor::createShaderPrograms() m_vertexCoordEntry = m_program->attributeLocation("vertexCoordEntry"); m_textureCoordEntry = m_program->attributeLocation("textureCoordEntry"); - m_textureEntry = m_program->attributeLocation("texture"); + m_textureEntry = m_program->uniformLocation("texture"); } void QEGLPlatformCursor::createCursorTexture(uint *texture, const QImage &image) diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp index a730993df7..0d1f9455e1 100644 --- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp +++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp @@ -659,6 +659,9 @@ QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, void *usrPtr) QFontEngine *QFontconfigDatabase::fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference) { QFontEngineFT *engine = static_cast<QFontEngineFT*>(QBasicFontDatabase::fontEngine(fontData, pixelSize, hintingPreference)); + if (engine == 0) + return 0; + QFontDef fontDef = engine->fontDef; QFontEngineFT::GlyphFormat format; diff --git a/src/platformsupport/linuxaccessibility/atspiadaptor.cpp b/src/platformsupport/linuxaccessibility/atspiadaptor.cpp index 1ccab0a859..0fa1d96242 100644 --- a/src/platformsupport/linuxaccessibility/atspiadaptor.cpp +++ b/src/platformsupport/linuxaccessibility/atspiadaptor.cpp @@ -1024,15 +1024,28 @@ void AtSpiAdaptor::notify(QAccessibleEvent *event) case QAccessible::ValueChanged: { if (sendObject || sendObject_value_changed || sendObject_property_change_accessible_value) { QAccessibleInterface * iface = event->accessibleInterface(); - if (!iface || !iface->valueInterface()) { - qWarning() << "ValueChanged event from invalid accessible: " << iface; + if (!iface) { + qWarning() << "ValueChanged event from invalid accessible."; return; } - - QString path = pathForInterface(iface); - QVariantList args = packDBusSignalArguments(QLatin1String("accessible-value"), 0, 0, variantForPath(path)); - sendDBusSignal(path, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_OBJECT), - QLatin1String("PropertyChange"), args); + if (iface->valueInterface()) { + QString path = pathForInterface(iface); + QVariantList args = packDBusSignalArguments(QLatin1String("accessible-value"), 0, 0, variantForPath(path)); + sendDBusSignal(path, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_OBJECT), + QLatin1String("PropertyChange"), args); + } else if (iface->role() == QAccessible::ComboBox) { + // Combo Box with AT-SPI likes to be special + // It requires a name-change to update caches and then selection-changed + QString path = pathForInterface(iface); + QVariantList args1 = packDBusSignalArguments(QLatin1String("accessible-name"), 0, 0, variantForPath(path)); + sendDBusSignal(path, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_OBJECT), + QLatin1String("PropertyChange"), args1); + QVariantList args2 = packDBusSignalArguments(QString(), 0, 0, QVariant::fromValue(QDBusVariant(QVariant(0)))); + sendDBusSignal(path, QLatin1String(ATSPI_DBUS_INTERFACE_EVENT_OBJECT), + QLatin1String("SelectionChanged"), args2); + } else { + qWarning() << "ValueChanged event and no ValueInterface or ComboBox: " << iface; + } } break; } |