diff options
Diffstat (limited to 'src')
31 files changed, 476 insertions, 181 deletions
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index bc93b1f477..934916514a 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -4268,8 +4268,10 @@ bool QInternal::activateCallbacks(Callback cb, void **parameters) Compares the floating point value \a p1 and \a p2 and returns \c true if they are considered equal, otherwise \c false. - Note that comparing values where either \a p1 or \a p2 is 0.0 will not work. - The solution to this is to compare against values greater than or equal to 1.0. + Note that comparing values where either \a p1 or \a p2 is 0.0 will not work, + nor does comparing values where one of the values is NaN or infinity. + If one of the values is always 0.0, use qFuzzyIsNull instead. If one of the + values is likely to be 0.0, one solution is to add 1.0 to both values. \snippet code/src_corelib_global_qglobal.cpp 46 diff --git a/src/corelib/global/qversiontagging.h b/src/corelib/global/qversiontagging.h index 1e276dc3e0..3ed02c7376 100644 --- a/src/corelib/global/qversiontagging.h +++ b/src/corelib/global/qversiontagging.h @@ -60,7 +60,7 @@ QT_BEGIN_NAMESPACE * There will only be one copy of the section in the output library or application. */ -#if defined(QT_BUILD_CORE_LIB) || defined(QT_BOOTSTRAPPED) || defined(QT_NO_VERSION_TAGGING) +#if defined(QT_BUILD_CORE_LIB) || defined(QT_BOOTSTRAPPED) || defined(QT_NO_VERSION_TAGGING) || defined(QT_STATIC) // don't make tags in QtCore, bootstrapped systems or if the user asked not to #elif defined(Q_CC_GNU) && !defined(Q_OS_ANDROID) # if defined(Q_PROCESSOR_X86) && (defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD_KERNEL)) diff --git a/src/corelib/io/qfilesystemwatcher_fsevents.mm b/src/corelib/io/qfilesystemwatcher_fsevents.mm index 174ebb9d4a..e88b4e4678 100644 --- a/src/corelib/io/qfilesystemwatcher_fsevents.mm +++ b/src/corelib/io/qfilesystemwatcher_fsevents.mm @@ -349,7 +349,7 @@ QStringList QFseventsFileSystemWatcherEngine::addPaths(const QStringList &paths, QStringList p = paths; QMutableListIterator<QString> it(p); while (it.hasNext()) { - QString origPath = it.next(); + QString origPath = it.next().normalized(QString::NormalizationForm_C); QString realPath = origPath; if (realPath.endsWith(QDir::separator())) realPath = realPath.mid(0, realPath.size() - 1); diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 69fd4f1e52..5ea4a0077b 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -487,48 +487,46 @@ static int ucstrncmp(const QChar *a, const QChar *b, int l) if (!l) return 0; - union { - const QChar *w; - const quint32 *d; - quintptr value; - } sa, sb; - sa.w = a; - sb.w = b; - // check alignment - if ((sa.value & 2) == (sb.value & 2)) { + if ((reinterpret_cast<quintptr>(a) & 2) == (reinterpret_cast<quintptr>(b) & 2)) { // both addresses have the same alignment - if (sa.value & 2) { + if (reinterpret_cast<quintptr>(a) & 2) { // both addresses are not aligned to 4-bytes boundaries // compare the first character - if (*sa.w != *sb.w) - return sa.w->unicode() - sb.w->unicode(); + if (*a != *b) + return a->unicode() - b->unicode(); --l; - ++sa.w; - ++sb.w; + ++a; + ++b; // now both addresses are 4-bytes aligned } // both addresses are 4-bytes aligned // do a fast 32-bit comparison - const quint32 *e = sa.d + (l >> 1); - for ( ; sa.d != e; ++sa.d, ++sb.d) { - if (*sa.d != *sb.d) { - if (*sa.w != *sb.w) - return sa.w->unicode() - sb.w->unicode(); - return sa.w[1].unicode() - sb.w[1].unicode(); + const quint32 *da = reinterpret_cast<const quint32 *>(a); + const quint32 *db = reinterpret_cast<const quint32 *>(b); + const quint32 *e = da + (l >> 1); + for ( ; da != e; ++da, ++db) { + if (*da != *db) { + a = reinterpret_cast<const QChar *>(da); + b = reinterpret_cast<const QChar *>(db); + if (*a != *b) + return a->unicode() - b->unicode(); + return a[1].unicode() - b[1].unicode(); } } // do we have a tail? - return (l & 1) ? sa.w->unicode() - sb.w->unicode() : 0; + a = reinterpret_cast<const QChar *>(da); + b = reinterpret_cast<const QChar *>(db); + return (l & 1) ? a->unicode() - b->unicode() : 0; } else { // one of the addresses isn't 4-byte aligned but the other is - const QChar *e = sa.w + l; - for ( ; sa.w != e; ++sa.w, ++sb.w) { - if (*sa.w != *sb.w) - return sa.w->unicode() - sb.w->unicode(); + const QChar *e = a + l; + for ( ; a != e; ++a, ++b) { + if (*a != *b) + return a->unicode() - b->unicode(); } } return 0; diff --git a/src/gui/gui.pro b/src/gui/gui.pro index 462f133ff8..09bdb225e9 100644 --- a/src/gui/gui.pro +++ b/src/gui/gui.pro @@ -9,6 +9,7 @@ QMAKE_DOCS = $$PWD/doc/qtgui.qdocconf MODULE_PLUGIN_TYPES = \ platforms \ + platforms/darwin \ xcbglintegrations \ platformthemes \ platforminputcontexts \ diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 353b623a3b..142fd66947 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -351,6 +351,16 @@ void QWindowGeometrySpecification::applyTo(QWindow *window) const static QWindowGeometrySpecification windowGeometrySpecification = Q_WINDOW_GEOMETRY_SPECIFICATION_INITIALIZER; /*! + \macro qGuiApp + \relates QGuiApplication + + A global pointer referring to the unique application object. + Only valid for use when that object is a QGuiApplication. + + \sa QCoreApplication::instance(), qApp +*/ + +/*! \class QGuiApplication \brief The QGuiApplication class manages the GUI application's control flow and main settings. diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index 283d03f22c..c61c749148 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -807,7 +807,8 @@ QStringList QPlatformFontDatabase::fallbacksForFamily(const QString &family, QFo Q_UNUSED(family); Q_UNUSED(styleHint); - QStringList retList; + QStringList preferredFallbacks; + QStringList otherFallbacks; size_t writingSystem = std::find(scriptForWritingSystem, scriptForWritingSystem + QFontDatabase::WritingSystemsCount, @@ -828,18 +829,18 @@ QStringList QPlatformFontDatabase::fallbacksForFamily(const QString &family, QFo QtFontFoundry *foundry = f->foundries[j]; for (int k = 0; k < foundry->count; ++k) { - if (style == foundry->styles[k]->key.style) { - if (foundry->name.isEmpty()) - retList.append(f->name); - else - retList.append(f->name + QLatin1String(" [") + foundry->name + QLatin1Char(']')); - break; - } + QString name = foundry->name.isEmpty() + ? f->name + : f->name + QLatin1String(" [") + foundry->name + QLatin1Char(']'); + if (style == foundry->styles[k]->key.style) + preferredFallbacks.append(name); + else + otherFallbacks.append(name); } } } - return retList; + return preferredFallbacks + otherFallbacks; } static void initializeDb(); @@ -1659,9 +1660,6 @@ bool QFontDatabase::isFixedPitch(const QString &family, bool QFontDatabase::isBitmapScalable(const QString &family, const QString &style) const { - if (QGuiApplicationPrivate::platformIntegration()->fontDatabase()->fontsAlwaysScalable()) - return true; - bool bitmapScalable = false; QString familyName, foundryName; parseFontName(family, foundryName, familyName); @@ -1702,9 +1700,6 @@ bool QFontDatabase::isBitmapScalable(const QString &family, */ bool QFontDatabase::isSmoothlyScalable(const QString &family, const QString &style) const { - if (QGuiApplicationPrivate::platformIntegration()->fontDatabase()->fontsAlwaysScalable()) - return true; - bool smoothScalable = false; QString familyName, foundryName; parseFontName(family, foundryName, familyName); diff --git a/src/platformsupport/clipboard/qmacmime.mm b/src/platformsupport/clipboard/qmacmime.mm index f2b9afa2b5..70de90c21d 100644 --- a/src/platformsupport/clipboard/qmacmime.mm +++ b/src/platformsupport/clipboard/qmacmime.mm @@ -414,8 +414,7 @@ QVariant QMacPasteboardMimeUnicodeText::convertToMime(const QString &mimetype, Q if (flavor == QLatin1String("public.utf8-plain-text")) { ret = QString::fromUtf8(firstData); } else if (flavor == QLatin1String("public.utf16-plain-text")) { - ret = QString(reinterpret_cast<const QChar *>(firstData.constData()), - firstData.size() / sizeof(QChar)); + ret = QTextCodec::codecForName("UTF-16")->toUnicode(firstData); } else { qWarning("QMime::convertToMime: unhandled mimetype: %s", qPrintable(mimetype)); } @@ -429,7 +428,7 @@ QList<QByteArray> QMacPasteboardMimeUnicodeText::convertFromMime(const QString & if (flavor == QLatin1String("public.utf8-plain-text")) ret.append(string.toUtf8()); else if (flavor == QLatin1String("public.utf16-plain-text")) - ret.append(QByteArray((char*)string.utf16(), string.length()*2)); + ret.append(QTextCodec::codecForName("UTF-16")->fromUnicode(string)); return ret; } diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.h b/src/plugins/platforms/cocoa/qcocoamenubar.h index 7ce2059450..4870ca4103 100644 --- a/src/plugins/platforms/cocoa/qcocoamenubar.h +++ b/src/plugins/platforms/cocoa/qcocoamenubar.h @@ -76,6 +76,7 @@ private: static QCocoaWindow *findWindowForMenubar(); static QCocoaMenuBar *findGlobalMenubar(); + bool needsImmediateUpdate(); bool shouldDisable(QCocoaWindow *active) const; NSMenuItem *nativeItemForMenu(QCocoaMenu *menu) const; diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.mm b/src/plugins/platforms/cocoa/qcocoamenubar.mm index 1c50c3b032..c6e9bd6373 100644 --- a/src/plugins/platforms/cocoa/qcocoamenubar.mm +++ b/src/plugins/platforms/cocoa/qcocoamenubar.mm @@ -95,6 +95,32 @@ QCocoaMenuBar::~QCocoaMenuBar() } } +bool QCocoaMenuBar::needsImmediateUpdate() +{ + if (m_window && m_window->window()->isActive()) { + return true; + } else if (!m_window) { + // Only update if the focus/active window has no + // menubar, which means it'll be using this menubar. + // This is to avoid a modification in a parentless + // menubar to affect a window-assigned menubar. + QWindow *fw = QGuiApplication::focusWindow(); + if (!fw) { + // Same if there's no focus window, BTW. + return true; + } else { + QCocoaWindow *cw = static_cast<QCocoaWindow *>(fw->handle()); + if (cw && !cw->menubar()) + return true; + } + } + + // Either the menubar is attached to a non-active window, + // or the application's focus window has its own menubar + // (which is different from this one) + return false; +} + void QCocoaMenuBar::insertMenu(QPlatformMenu *platformMenu, QPlatformMenu *before) { QCocoaMenu *menu = static_cast<QCocoaMenu *>(platformMenu); @@ -135,7 +161,7 @@ void QCocoaMenuBar::insertMenu(QPlatformMenu *platformMenu, QPlatformMenu *befor syncMenu(menu); - if (m_window && m_window->window()->isActive()) + if (needsImmediateUpdate()) updateMenuBarImmediately(); } diff --git a/src/plugins/platforms/ios/ios.pro b/src/plugins/platforms/ios/ios.pro index 7b0a573ffa..594ccefcf1 100644 --- a/src/plugins/platforms/ios/ios.pro +++ b/src/plugins/platforms/ios/ios.pro @@ -1,65 +1,2 @@ -TARGET = qios - -QT += core-private gui-private platformsupport-private -LIBS += -framework Foundation -framework UIKit -framework QuartzCore -framework AssetsLibrary -framework AudioToolbox - -OBJECTIVE_SOURCES = \ - plugin.mm \ - qiosintegration.mm \ - qioseventdispatcher.mm \ - qioswindow.mm \ - qiosscreen.mm \ - qiosbackingstore.mm \ - qiosapplicationdelegate.mm \ - qiosapplicationstate.mm \ - qiosviewcontroller.mm \ - qioscontext.mm \ - qiosinputcontext.mm \ - qiostheme.mm \ - qiosglobal.mm \ - qiosservices.mm \ - quiview.mm \ - qiosclipboard.mm \ - quiaccessibilityelement.mm \ - qiosplatformaccessibility.mm \ - qiostextresponder.mm \ - qiosmenu.mm \ - qiosfileengineassetslibrary.mm \ - qiosfiledialog.mm \ - qiosmessagedialog.mm \ - qiostextinputoverlay.mm - -HEADERS = \ - qiosintegration.h \ - qioseventdispatcher.h \ - qioswindow.h \ - qiosscreen.h \ - qiosbackingstore.h \ - qiosapplicationdelegate.h \ - qiosapplicationstate.h \ - qiosviewcontroller.h \ - qioscontext.h \ - qiosinputcontext.h \ - qiostheme.h \ - qiosglobal.h \ - qiosservices.h \ - quiview.h \ - qiosclipboard.h \ - quiaccessibilityelement.h \ - qiosplatformaccessibility.h \ - qiostextresponder.h \ - qiosmenu.h \ - qiosfileenginefactory.h \ - qiosfileengineassetslibrary.h \ - qiosfiledialog.h \ - qiosmessagedialog.h \ - qiostextinputoverlay.h - -OTHER_FILES = \ - quiview_textinput.mm \ - quiview_accessibility.mm - -PLUGIN_TYPE = platforms -PLUGIN_CLASS_NAME = QIOSIntegrationPlugin -!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - -load(qt_plugin) +TEMPLATE = subdirs +SUBDIRS = kernel.pro optional diff --git a/src/plugins/platforms/ios/kernel.pro b/src/plugins/platforms/ios/kernel.pro new file mode 100644 index 0000000000..d8235ee011 --- /dev/null +++ b/src/plugins/platforms/ios/kernel.pro @@ -0,0 +1,63 @@ +TARGET = qios + +QT += core-private gui-private platformsupport-private +LIBS += -framework Foundation -framework UIKit -framework QuartzCore + +OBJECTIVE_SOURCES = \ + plugin.mm \ + qiosintegration.mm \ + qioseventdispatcher.mm \ + qioswindow.mm \ + qiosscreen.mm \ + qiosbackingstore.mm \ + qiosapplicationdelegate.mm \ + qiosapplicationstate.mm \ + qiosviewcontroller.mm \ + qioscontext.mm \ + qiosinputcontext.mm \ + qiostheme.mm \ + qiosglobal.mm \ + qiosservices.mm \ + quiview.mm \ + qiosclipboard.mm \ + quiaccessibilityelement.mm \ + qiosplatformaccessibility.mm \ + qiostextresponder.mm \ + qiosmenu.mm \ + qiosfiledialog.mm \ + qiosmessagedialog.mm \ + qiostextinputoverlay.mm + +HEADERS = \ + qiosintegration.h \ + qioseventdispatcher.h \ + qioswindow.h \ + qiosscreen.h \ + qiosbackingstore.h \ + qiosapplicationdelegate.h \ + qiosapplicationstate.h \ + qiosviewcontroller.h \ + qioscontext.h \ + qiosinputcontext.h \ + qiostheme.h \ + qiosglobal.h \ + qiosservices.h \ + quiview.h \ + qiosclipboard.h \ + quiaccessibilityelement.h \ + qiosplatformaccessibility.h \ + qiostextresponder.h \ + qiosmenu.h \ + qiosfiledialog.h \ + qiosmessagedialog.h \ + qiostextinputoverlay.h + + +OTHER_FILES = \ + quiview_textinput.mm \ + quiview_accessibility.mm + +PLUGIN_TYPE = platforms +PLUGIN_CLASS_NAME = QIOSIntegrationPlugin +!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - +load(qt_plugin) diff --git a/src/plugins/platforms/ios/optional/nsphotolibrarysupport/nsphotolibrarysupport.pro b/src/plugins/platforms/ios/optional/nsphotolibrarysupport/nsphotolibrarysupport.pro new file mode 100644 index 0000000000..f4588dda03 --- /dev/null +++ b/src/plugins/platforms/ios/optional/nsphotolibrarysupport/nsphotolibrarysupport.pro @@ -0,0 +1,22 @@ +TARGET = qiosnsphotolibrarysupport + +QT += core gui gui-private +LIBS += -framework UIKit -framework AssetsLibrary + +HEADERS = \ + qiosfileengineassetslibrary.h \ + qiosfileenginefactory.h \ + qiosimagepickercontroller.h + +OBJECTIVE_SOURCES = \ + plugin.mm \ + qiosfileengineassetslibrary.mm \ + qiosimagepickercontroller.mm \ + +OTHER_FILES = \ + plugin.json + +PLUGIN_CLASS_NAME = QIosOptionalPlugin_NSPhotoLibrary +PLUGIN_EXTENDS = - +PLUGIN_TYPE = platforms/darwin +load(qt_plugin) diff --git a/src/plugins/platforms/ios/optional/nsphotolibrarysupport/plugin.json b/src/plugins/platforms/ios/optional/nsphotolibrarysupport/plugin.json new file mode 100644 index 0000000000..4491fb3d59 --- /dev/null +++ b/src/plugins/platforms/ios/optional/nsphotolibrarysupport/plugin.json @@ -0,0 +1,3 @@ +{ + "Keys": [ "NSPhotoLibrarySupport" ] +} diff --git a/src/plugins/platforms/ios/optional/nsphotolibrarysupport/plugin.mm b/src/plugins/platforms/ios/optional/nsphotolibrarysupport/plugin.mm new file mode 100644 index 0000000000..2ec0d33a41 --- /dev/null +++ b/src/plugins/platforms/ios/optional/nsphotolibrarysupport/plugin.mm @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "../../qiosoptionalplugininterface.h" +#include "../../qiosfiledialog.h" + +#include "qiosimagepickercontroller.h" +#include "qiosfileenginefactory.h" + +QT_BEGIN_NAMESPACE + +class QIosOptionalPlugin_NSPhotoLibrary : public QObject, QIosOptionalPluginInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID QIosOptionalPluginInterface_iid FILE "plugin.json") + Q_INTERFACES(QIosOptionalPluginInterface) + +public: + explicit QIosOptionalPlugin_NSPhotoLibrary(QObject* = 0) {}; + ~QIosOptionalPlugin_NSPhotoLibrary() {} + + UIViewController* createImagePickerController(QIOSFileDialog *fileDialog) const override + { + return [[[QIOSImagePickerController alloc] initWithQIOSFileDialog:fileDialog] autorelease]; + } + +private: + QIOSFileEngineFactory m_fileEngineFactory; + +}; + +QT_END_NAMESPACE + +#include "plugin.moc" diff --git a/src/plugins/platforms/ios/qiosfileengineassetslibrary.h b/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosfileengineassetslibrary.h index 06f2e8d2ca..2d0101e8ae 100644 --- a/src/plugins/platforms/ios/qiosfileengineassetslibrary.h +++ b/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosfileengineassetslibrary.h @@ -51,20 +51,20 @@ public: QIOSFileEngineAssetsLibrary(const QString &fileName); ~QIOSFileEngineAssetsLibrary(); - bool open(QIODevice::OpenMode openMode) Q_DECL_OVERRIDE; - bool close() Q_DECL_OVERRIDE; - FileFlags fileFlags(FileFlags type) const Q_DECL_OVERRIDE; - qint64 size() const Q_DECL_OVERRIDE; - qint64 read(char *data, qint64 maxlen) Q_DECL_OVERRIDE; - qint64 pos() const Q_DECL_OVERRIDE; - bool seek(qint64 pos) Q_DECL_OVERRIDE; - QString fileName(FileName file) const Q_DECL_OVERRIDE; - void setFileName(const QString &file) Q_DECL_OVERRIDE; - QStringList entryList(QDir::Filters filters, const QStringList &filterNames) const Q_DECL_OVERRIDE; + bool open(QIODevice::OpenMode openMode) override; + bool close() override; + FileFlags fileFlags(FileFlags type) const override; + qint64 size() const override; + qint64 read(char *data, qint64 maxlen) override; + qint64 pos() const override; + bool seek(qint64 pos) override; + QString fileName(FileName file) const override; + void setFileName(const QString &file) override; + QStringList entryList(QDir::Filters filters, const QStringList &filterNames) const override; #ifndef QT_NO_FILESYSTEMITERATOR - Iterator *beginEntryList(QDir::Filters filters, const QStringList &filterNames) Q_DECL_OVERRIDE; - Iterator *endEntryList() Q_DECL_OVERRIDE; + Iterator *beginEntryList(QDir::Filters filters, const QStringList &filterNames) override; + Iterator *endEntryList() override; #endif void setError(QFile::FileError error, const QString &str) { QAbstractFileEngine::setError(error, str); } diff --git a/src/plugins/platforms/ios/qiosfileengineassetslibrary.mm b/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosfileengineassetslibrary.mm index 560c54924a..560c54924a 100644 --- a/src/plugins/platforms/ios/qiosfileengineassetslibrary.mm +++ b/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosfileengineassetslibrary.mm diff --git a/src/plugins/platforms/ios/qiosfileenginefactory.h b/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosfileenginefactory.h index b71fa64460..b71fa64460 100644 --- a/src/plugins/platforms/ios/qiosfileenginefactory.h +++ b/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosfileenginefactory.h diff --git a/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosimagepickercontroller.h b/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosimagepickercontroller.h new file mode 100644 index 0000000000..df3f6b9fa3 --- /dev/null +++ b/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosimagepickercontroller.h @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#import <UIKit/UIKit.h> + +#include "../../qiosfiledialog.h" + +@interface QIOSImagePickerController : UIImagePickerController <UIImagePickerControllerDelegate, UINavigationControllerDelegate> { + QIOSFileDialog *m_fileDialog; +} +- (id)initWithQIOSFileDialog:(QIOSFileDialog *)fileDialog; +@end diff --git a/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosimagepickercontroller.mm b/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosimagepickercontroller.mm new file mode 100644 index 0000000000..f9662b964a --- /dev/null +++ b/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosimagepickercontroller.mm @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#import <UIKit/UIKit.h> + +#include "qiosimagepickercontroller.h" + +@implementation QIOSImagePickerController + +- (id)initWithQIOSFileDialog:(QIOSFileDialog *)fileDialog +{ + self = [super init]; + if (self) { + m_fileDialog = fileDialog; + [self setSourceType:UIImagePickerControllerSourceTypePhotoLibrary]; + [self setDelegate:self]; + } + return self; +} + +- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info +{ + Q_UNUSED(picker); + NSURL *url = [info objectForKey:UIImagePickerControllerReferenceURL]; + QUrl fileUrl = QUrl::fromLocalFile(QString::fromNSString([url description])); + m_fileDialog->selectedFilesChanged(QList<QUrl>() << fileUrl); + emit m_fileDialog->accept(); +} + +- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker +{ + Q_UNUSED(picker) + emit m_fileDialog->reject(); +} + +@end diff --git a/src/plugins/platforms/ios/optional/optional.pro b/src/plugins/platforms/ios/optional/optional.pro new file mode 100644 index 0000000000..5e3421a025 --- /dev/null +++ b/src/plugins/platforms/ios/optional/optional.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS = nsphotolibrarysupport diff --git a/src/plugins/platforms/ios/qiosfiledialog.h b/src/plugins/platforms/ios/qiosfiledialog.h index 855bab0424..937b56e2f6 100644 --- a/src/plugins/platforms/ios/qiosfiledialog.h +++ b/src/plugins/platforms/ios/qiosfiledialog.h @@ -72,6 +72,8 @@ private: QList<QUrl> m_selection; QEventLoop m_eventLoop; UIViewController *m_viewController; + + bool showImagePickerDialog(QWindow *parent); }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosfiledialog.mm b/src/plugins/platforms/ios/qiosfiledialog.mm index 70536fc5dc..c5722d33f8 100644 --- a/src/plugins/platforms/ios/qiosfiledialog.mm +++ b/src/plugins/platforms/ios/qiosfiledialog.mm @@ -37,52 +37,18 @@ ** ****************************************************************************/ -#include "qiosfiledialog.h" - #import <UIKit/UIKit.h> #include <QtCore/qstandardpaths.h> #include <QtGui/qwindow.h> +#include <QDebug> -@interface QIOSImagePickerController : UIImagePickerController <UIImagePickerControllerDelegate, UINavigationControllerDelegate> { - QIOSFileDialog *m_fileDialog; -} -@end - -@implementation QIOSImagePickerController - -- (id)initWithQIOSFileDialog:(QIOSFileDialog *)fileDialog -{ - self = [super init]; - if (self) { - m_fileDialog = fileDialog; - [self setSourceType:UIImagePickerControllerSourceTypePhotoLibrary]; - [self setDelegate:self]; - } - return self; -} - -- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info -{ - Q_UNUSED(picker); - NSURL *url = [info objectForKey:UIImagePickerControllerReferenceURL]; - QUrl fileUrl = QUrl::fromLocalFile(QString::fromNSString([url description])); - m_fileDialog->selectedFilesChanged(QList<QUrl>() << fileUrl); - emit m_fileDialog->accept(); -} - -- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker -{ - Q_UNUSED(picker) - emit m_fileDialog->reject(); -} - -@end - -// -------------------------------------------------------------------------- +#include "qiosfiledialog.h" +#include "qiosintegration.h" +#include "qiosoptionalplugininterface.h" QIOSFileDialog::QIOSFileDialog() - : m_viewController(0) + : m_viewController(Q_NULLPTR) { } @@ -104,17 +70,36 @@ bool QIOSFileDialog::show(Qt::WindowFlags windowFlags, Qt::WindowModality window bool acceptOpen = options()->acceptMode() == QFileDialogOptions::AcceptOpen; QString directory = options()->initialDirectory().toLocalFile(); - if (acceptOpen && directory.startsWith(QLatin1String("assets-library:"))) { - m_viewController = [[QIOSImagePickerController alloc] initWithQIOSFileDialog:this]; - UIWindow *window = parent ? reinterpret_cast<UIView *>(parent->winId()).window - : [UIApplication sharedApplication].keyWindow; - [window.rootViewController presentViewController:m_viewController animated:YES completion:nil]; - return true; - } + if (acceptOpen && directory.startsWith(QLatin1String("assets-library:"))) + return showImagePickerDialog(parent); return false; } +bool QIOSFileDialog::showImagePickerDialog(QWindow *parent) +{ + if (!m_viewController) { + QFactoryLoader *plugins = QIOSIntegration::instance()->optionalPlugins(); + for (int i = 0; i < plugins->metaData().size(); ++i) { + QIosOptionalPluginInterface *plugin = qobject_cast<QIosOptionalPluginInterface *>(plugins->instance(i)); + m_viewController = [plugin->createImagePickerController(this) retain]; + if (m_viewController) + break; + } + } + + if (!m_viewController) { + qWarning() << "QIOSFileDialog: Could not resolve Qt plugin that gives access to photos on iOS"; + return false; + } + + UIWindow *window = parent ? reinterpret_cast<UIView *>(parent->winId()).window + : [UIApplication sharedApplication].keyWindow; + [window.rootViewController presentViewController:m_viewController animated:YES completion:nil]; + + return true; +} + void QIOSFileDialog::hide() { // QFileDialog will remember the last directory set, and open subsequent dialogs in the same @@ -126,6 +111,8 @@ void QIOSFileDialog::hide() emit directoryEntered(QUrl::fromLocalFile(QDir::currentPath())); [m_viewController dismissViewControllerAnimated:YES completion:nil]; + [m_viewController release]; + m_viewController = Q_NULLPTR; m_eventLoop.exit(); } diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h index a50d9aa571..35f12bcb56 100644 --- a/src/plugins/platforms/ios/qiosintegration.h +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -44,8 +44,9 @@ #include <qpa/qplatformnativeinterface.h> #include <qpa/qwindowsysteminterface.h> +#include <QtCore/private/qfactoryloader_p.h> + #include "qiosapplicationstate.h" -#include "qiosfileenginefactory.h" #include "qiostextinputoverlay.h" QT_BEGIN_NAMESPACE @@ -100,6 +101,8 @@ public: void setDebugWindowManagement(bool); bool debugWindowManagement() const; + QFactoryLoader *optionalPlugins() { return m_optionalPlugins; } + private: QPlatformFontDatabase *m_fontDatabase; QPlatformClipboard *m_clipboard; @@ -108,7 +111,7 @@ private: QIOSApplicationState m_applicationState; QIOSServices *m_platformServices; mutable QPlatformAccessibility *m_accessibility; - QIOSFileEngineFactory m_fileEngineFactory; + QFactoryLoader *m_optionalPlugins; QIOSTextInputOverlay m_textInputOverlay; bool m_debugWindowManagement; diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index fa12d54b28..a9435ef15a 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -49,6 +49,7 @@ #include "qiosinputcontext.h" #include "qiostheme.h" #include "qiosservices.h" +#include "qiosoptionalplugininterface.h" #include <QtGui/private/qguiapplication_p.h> @@ -76,6 +77,7 @@ QIOSIntegration::QIOSIntegration() , m_inputContext(0) , m_platformServices(new QIOSServices) , m_accessibility(0) + , m_optionalPlugins(new QFactoryLoader(QIosOptionalPluginInterface_iid, QLatin1String("/platforms/darwin"))) , m_debugWindowManagement(false) { if (Q_UNLIKELY(![UIApplication sharedApplication])) { @@ -120,6 +122,9 @@ QIOSIntegration::QIOSIntegration() m_touchDevice->setCapabilities(touchCapabilities); QWindowSystemInterface::registerTouchDevice(m_touchDevice); QMacInternalPasteboardMime::initializeMimeTypes(); + + for (int i = 0; i < m_optionalPlugins->metaData().size(); ++i) + qobject_cast<QIosOptionalPluginInterface *>(m_optionalPlugins->instance(i))->initPlugin(); } QIOSIntegration::~QIOSIntegration() @@ -142,6 +147,9 @@ QIOSIntegration::~QIOSIntegration() delete m_accessibility; m_accessibility = 0; + + delete m_optionalPlugins; + m_optionalPlugins = 0; } bool QIOSIntegration::hasCapability(Capability cap) const diff --git a/src/plugins/platforms/ios/qiosoptionalplugininterface.h b/src/plugins/platforms/ios/qiosoptionalplugininterface.h new file mode 100644 index 0000000000..bcb8978e02 --- /dev/null +++ b/src/plugins/platforms/ios/qiosoptionalplugininterface.h @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QIOPLUGININTERFACE_H +#define QIOPLUGININTERFACE_H + +#include <QtCore/QtPlugin> + +#include "qiosfiledialog.h" + +QT_BEGIN_NAMESPACE + +Q_FORWARD_DECLARE_OBJC_CLASS(UIViewController); + +#define QIosOptionalPluginInterface_iid "org.qt-project.Qt.QPA.ios.optional" + +class QIosOptionalPluginInterface +{ +public: + virtual ~QIosOptionalPluginInterface() {} + virtual void initPlugin() const {}; + virtual UIViewController* createImagePickerController(QIOSFileDialog *) const { return Q_NULLPTR; }; +}; + +Q_DECLARE_INTERFACE(QIosOptionalPluginInterface, QIosOptionalPluginInterface_iid) + +QT_END_NAMESPACE + +#endif // QIOPLUGININTERFACE_H diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index 12616e14f6..094f2680c6 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -900,6 +900,9 @@ void QFileDialogPrivate::_q_goToUrl(const QUrl &url) {QStandardPaths::standardLocations(QStandardPaths::PicturesLocation).last()}, a native image picker dialog will be used for accessing the user's photo album. The filename returned can be loaded using QFile and related APIs. + For this to be enabled, the Info.plist assigned to QMAKE_INFO_PLIST in the + project file must contain the key \c NSPhotoLibraryUsageDescription. See + Info.plist documentation from Apple for more information regarding this key. This feature was added in Qt 5.5. */ void QFileDialog::setDirectory(const QString &directory) diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index 1b77d74cd0..ef046f3ef8 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -4216,13 +4216,10 @@ void QApplication::beep() \relates QApplication A global pointer referring to the unique application object. It is - equivalent to the pointer returned by the QCoreApplication::instance() - function except that, in GUI applications, it is a pointer to a - QApplication instance. + equivalent to QCoreApplication::instance(), but cast as a QApplication pointer, + so only valid when the unique application object is a QApplication. - Only one application object can be created. - - \sa QCoreApplication::instance() + \sa QCoreApplication::instance(), qGuiApp */ /*! diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index f3fbe13763..3e15b6977a 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -535,7 +535,7 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event) // activate window of the widget under mouse pointer if (!w->isActiveWindow()) { w->activateWindow(); - w->raise(); + w->window()->raise(); } QWindow *win = w->windowHandle(); diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm index 434ac9e7e7..2fbe3be62f 100644 --- a/src/widgets/styles/qmacstyle_mac.mm +++ b/src/widgets/styles/qmacstyle_mac.mm @@ -1039,6 +1039,8 @@ static QSize qt_aqua_get_known_size(QStyle::ContentsType ct, const QWidget *widg #if defined(QMAC_QAQUASTYLE_SIZE_CONSTRAIN) || defined(DEBUG_SIZE_CONSTRAINT) static QAquaWidgetSize qt_aqua_guess_size(const QWidget *widg, QSize large, QSize small, QSize mini) { + Q_UNUSED(widg); + if (large == QSize(-1, -1)) { if (small != QSize(-1, -1)) return QAquaSizeSmall; @@ -1054,7 +1056,7 @@ static QAquaWidgetSize qt_aqua_guess_size(const QWidget *widg, QSize large, QSiz } #ifndef QT_NO_MAINWINDOW - if (qobject_cast<QDockWidget *>(widg->window()) || qEnvironmentVariableIsSet("QWIDGET_ALL_SMALL")) { + if (qEnvironmentVariableIsSet("QWIDGET_ALL_SMALL")) { //if (small.width() != -1 || small.height() != -1) return QAquaSizeSmall; } else if (qEnvironmentVariableIsSet("QWIDGET_ALL_MINI")) { diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index 4287114ec3..e255a95ea2 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -3133,6 +3133,7 @@ void QComboBox::keyPressEvent(QKeyEvent *e) case Qt::Key_Up: if (e->modifiers() & Qt::ControlModifier) break; // pass to line edit for auto completion + // fall through case Qt::Key_PageUp: #ifdef QT_KEYPAD_NAVIGATION if (QApplication::keypadNavigationEnabled()) @@ -3220,6 +3221,7 @@ void QComboBox::keyPressEvent(QKeyEvent *e) switch (move) { case MoveFirst: newIndex = -1; + // fall through case MoveDown: newIndex++; while (newIndex < rowCount && !(d->model->index(newIndex, d->modelColumn, d->root).flags() & Qt::ItemIsEnabled)) @@ -3227,6 +3229,7 @@ void QComboBox::keyPressEvent(QKeyEvent *e) break; case MoveLast: newIndex = rowCount; + // fall through case MoveUp: newIndex--; while ((newIndex >= 0) && !(d->model->flags(d->model->index(newIndex,d->modelColumn,d->root)) & Qt::ItemIsEnabled)) |