summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mkspecs/features/mac/objective_c.prf2
-rw-r--r--mkspecs/features/moc.prf2
-rw-r--r--mkspecs/macx-ios-clang/features/default_post.prf8
-rw-r--r--qmake/doc/src/qmake-manual.qdoc6
-rw-r--r--qmake/generators/makefiledeps.cpp5
-rw-r--r--src/corelib/global/qglobal.cpp6
-rw-r--r--src/corelib/global/qversiontagging.h2
-rw-r--r--src/corelib/io/qfilesystemwatcher_fsevents.mm2
-rw-r--r--src/corelib/tools/qstring.cpp48
-rw-r--r--src/gui/gui.pro1
-rw-r--r--src/gui/kernel/qguiapplication.cpp10
-rw-r--r--src/gui/text/qfontdatabase.cpp25
-rw-r--r--src/platformsupport/clipboard/qmacmime.mm5
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenubar.h1
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenubar.mm28
-rw-r--r--src/plugins/platforms/ios/ios.pro67
-rw-r--r--src/plugins/platforms/ios/kernel.pro63
-rw-r--r--src/plugins/platforms/ios/optional/nsphotolibrarysupport/nsphotolibrarysupport.pro22
-rw-r--r--src/plugins/platforms/ios/optional/nsphotolibrarysupport/plugin.json3
-rw-r--r--src/plugins/platforms/ios/optional/nsphotolibrarysupport/plugin.mm64
-rw-r--r--src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosfileengineassetslibrary.h (renamed from src/plugins/platforms/ios/qiosfileengineassetslibrary.h)24
-rw-r--r--src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosfileengineassetslibrary.mm (renamed from src/plugins/platforms/ios/qiosfileengineassetslibrary.mm)0
-rw-r--r--src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosfileenginefactory.h (renamed from src/plugins/platforms/ios/qiosfileenginefactory.h)0
-rw-r--r--src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosimagepickercontroller.h42
-rw-r--r--src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosimagepickercontroller.mm66
-rw-r--r--src/plugins/platforms/ios/optional/optional.pro2
-rw-r--r--src/plugins/platforms/ios/qiosfiledialog.h2
-rw-r--r--src/plugins/platforms/ios/qiosfiledialog.mm79
-rw-r--r--src/plugins/platforms/ios/qiosintegration.h7
-rw-r--r--src/plugins/platforms/ios/qiosintegration.mm8
-rw-r--r--src/plugins/platforms/ios/qiosoptionalplugininterface.h59
-rw-r--r--src/widgets/dialogs/qfiledialog.cpp3
-rw-r--r--src/widgets/kernel/qapplication.cpp9
-rw-r--r--src/widgets/kernel/qwidgetwindow.cpp2
-rw-r--r--src/widgets/styles/qmacstyle_mac.mm4
-rw-r--r--src/widgets/widgets/qcombobox.cpp3
-rw-r--r--tests/auto/corelib/io/qfile/tst_qfile.cpp2
-rw-r--r--tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp21
-rw-r--r--tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp106
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp40
-rw-r--r--tests/auto/widgets/widgets/qmenubar/qmenubar.pro5
-rw-r--r--tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp24
-rw-r--r--tests/auto/widgets/widgets/qmenubar/tst_qmenubar_mac.mm44
43 files changed, 673 insertions, 249 deletions
diff --git a/mkspecs/features/mac/objective_c.prf b/mkspecs/features/mac/objective_c.prf
index b3b1d4be99..ed1ad8ad38 100644
--- a/mkspecs/features/mac/objective_c.prf
+++ b/mkspecs/features/mac/objective_c.prf
@@ -1,6 +1,7 @@
# Objective-C/C++ sources go in SOURCES, like all other sources
SOURCES += $$OBJECTIVE_SOURCES
+unset(OBJECTIVE_SOURCES)
# Strip C/C++ flags from QMAKE_OBJECTIVE_CFLAGS just in case
QMAKE_OBJECTIVE_CFLAGS -= $$QMAKE_CFLAGS $$QMAKE_CXXFLAGS
@@ -8,3 +9,4 @@ QMAKE_OBJECTIVE_CFLAGS -= $$QMAKE_CFLAGS $$QMAKE_CXXFLAGS
# Add Objective-C/C++ flags to C/C++ flags, the compiler can handle it
QMAKE_CFLAGS += $$QMAKE_OBJECTIVE_CFLAGS
QMAKE_CXXFLAGS += $$QMAKE_OBJECTIVE_CFLAGS
+unset(QMAKE_OBJECTIVE_CFLAGS)
diff --git a/mkspecs/features/moc.prf b/mkspecs/features/moc.prf
index 8ddfc38c63..9d3c3353cc 100644
--- a/mkspecs/features/moc.prf
+++ b/mkspecs/features/moc.prf
@@ -56,7 +56,7 @@ moc_source.CONFIG = no_link moc_verify
moc_source.dependency_type = TYPE_C
moc_source.commands = ${QMAKE_FUNC_mocCmdBase} ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT}
moc_source.output = $$MOC_DIR/$${QMAKE_CPP_MOD_MOC}${QMAKE_FILE_BASE}$${QMAKE_EXT_CPP_MOC}
-moc_source.input = SOURCES OBJECTIVE_SOURCES
+moc_source.input = SOURCES
moc_source.name = MOC ${QMAKE_FILE_IN}
moc_source.depends += $$WIN_INCLUDETEMP
silent:moc_source.commands = @echo moc ${QMAKE_FILE_IN} && $$moc_source.commands
diff --git a/mkspecs/macx-ios-clang/features/default_post.prf b/mkspecs/macx-ios-clang/features/default_post.prf
index 37964b688b..ec2e2d509c 100644
--- a/mkspecs/macx-ios-clang/features/default_post.prf
+++ b/mkspecs/macx-ios-clang/features/default_post.prf
@@ -80,3 +80,11 @@ macx-xcode {
QMAKE_CXXFLAGS += $$arch_flags
QMAKE_LFLAGS += $$arch_flags
}
+
+!xcodebuild:equals(TEMPLATE, app):!isEmpty(QMAKE_INFO_PLIST) {
+ # Only link in photo library support if Info.plist contains
+ # NSPhotoLibraryUsageDescription. Otherwise it will be rejected from AppStore.
+ plist_path = $$absolute_path($$QMAKE_INFO_PLIST, $$_PRO_FILE_PWD_)
+ system("/usr/libexec/PlistBuddy -c 'Print NSPhotoLibraryUsageDescription' $$system_quote($$plist_path) &>/dev/null"): \
+ QTPLUGIN += qiosnsphotolibrarysupport
+}
diff --git a/qmake/doc/src/qmake-manual.qdoc b/qmake/doc/src/qmake-manual.qdoc
index 7135948832..5c17f895e3 100644
--- a/qmake/doc/src/qmake-manual.qdoc
+++ b/qmake/doc/src/qmake-manual.qdoc
@@ -1813,6 +1813,12 @@
which qmake will replace with the actual executable name. Other variables
include @ICON@, @TYPEINFO@, @LIBRARY@, and @SHORT_VERSION@.
+ If building for iOS, and the \c{.plist} file contains the key
+ \c NSPhotoLibraryUsageDescription, qmake will include an additional plugin
+ to the build that adds photo access support (to, e.g.,
+ \l{QFileDialog::setDirectory()}{QFile/QFileDialog}). See Info.plist
+ documentation from Apple for more information regarding this key.
+
\note Most of the time, the default \c{Info.plist} is good enough.
\section1 QMAKE_LFLAGS
diff --git a/qmake/generators/makefiledeps.cpp b/qmake/generators/makefiledeps.cpp
index 57cb0ea854..44f715346f 100644
--- a/qmake/generators/makefiledeps.cpp
+++ b/qmake/generators/makefiledeps.cpp
@@ -46,6 +46,7 @@
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <limits.h>
#if defined(_MSC_VER) && _MSC_VER >= 1400
#include <share.h>
#endif
@@ -979,9 +980,11 @@ bool QMakeSourceFileInfo::findMocs(SourceFile *file)
continue;
int matchlen = 0, extralines = 0;
+ size_t needle_len = strlen(interesting[interest]);
+ Q_ASSERT(needle_len <= INT_MAX);
if (matchWhileUnsplitting(buffer, buffer_len, y,
interesting[interest],
- strlen(interesting[interest]),
+ static_cast<int>(needle_len),
&matchlen, &extralines)
&& y + matchlen < buffer_len
&& !isCWordChar(buffer[y + matchlen])) {
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))
diff --git a/tests/auto/corelib/io/qfile/tst_qfile.cpp b/tests/auto/corelib/io/qfile/tst_qfile.cpp
index d6bc75317a..7752930ae4 100644
--- a/tests/auto/corelib/io/qfile/tst_qfile.cpp
+++ b/tests/auto/corelib/io/qfile/tst_qfile.cpp
@@ -3442,7 +3442,7 @@ void tst_QFile::autocloseHandle()
//file is closed, read should fail
char buf;
QCOMPARE((int)QT_READ(fd, &buf, 1), -1);
- QVERIFY(errno = EBADF);
+ QVERIFY(errno == EBADF);
}
{
diff --git a/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp b/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp
index 187f72d095..97b5e74bc2 100644
--- a/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp
+++ b/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp
@@ -73,6 +73,8 @@ private slots:
void signalsEmittedAfterFileMoved();
+ void watchUnicodeCharacters();
+
private:
QString m_tempDirPattern;
#endif // QT_NO_FILESYSTEMWATCHER
@@ -759,6 +761,25 @@ void tst_QFileSystemWatcher::signalsEmittedAfterFileMoved()
QVERIFY2(changedSpy.count() <= fileCount, changedSpy.receivedFilesMessage());
QTRY_COMPARE(changedSpy.count(), fileCount);
}
+
+void tst_QFileSystemWatcher::watchUnicodeCharacters()
+{
+ QTemporaryDir temporaryDirectory(m_tempDirPattern);
+ QVERIFY2(temporaryDirectory.isValid(), qPrintable(temporaryDirectory.errorString()));
+
+ QDir testDir(temporaryDirectory.path());
+ const QString subDir(QString::fromLatin1("caf\xe9"));
+ QVERIFY(testDir.mkdir(subDir));
+ testDir = QDir(temporaryDirectory.path() + QDir::separator() + subDir);
+
+ QFileSystemWatcher watcher;
+ QVERIFY(watcher.addPath(testDir.path()));
+
+ FileSystemWatcherSpy changedSpy(&watcher, FileSystemWatcherSpy::SpyOnDirectoryChanged);
+ QCOMPARE(changedSpy.count(), 0);
+ QVERIFY(testDir.mkdir("creme"));
+ QTRY_COMPARE(changedSpy.count(), 1);
+}
#endif // QT_NO_FILESYSTEMWATCHER
QTEST_MAIN(tst_QFileSystemWatcher)
diff --git a/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp b/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp
index 2635a2ed82..0f63baa0e6 100644
--- a/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp
+++ b/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp
@@ -1614,28 +1614,44 @@ class SetPage : public Operation
wizard->next();
}
QString describe() const { return QLatin1String("set page ") + QString::number(page); }
- const int page;
+ int page;
public:
- SetPage(int page) : page(page) {}
+ static QSharedPointer<SetPage> create(int page)
+ {
+ QSharedPointer<SetPage> o = QSharedPointer<SetPage>::create();
+ o->page = page;
+ return o;
+ }
};
class SetStyle : public Operation
{
void apply(QWizard *wizard) const { wizard->setWizardStyle(style); }
QString describe() const { return QLatin1String("set style ") + QString::number(style); }
- const QWizard::WizardStyle style;
+ QWizard::WizardStyle style;
public:
- SetStyle(QWizard::WizardStyle style) : style(style) {}
+ static QSharedPointer<SetStyle> create(QWizard::WizardStyle style)
+ {
+ QSharedPointer<SetStyle> o = QSharedPointer<SetStyle>::create();
+ o->style = style;
+ return o;
+ }
};
class SetOption : public Operation
{
void apply(QWizard *wizard) const { wizard->setOption(option, on); }
QString describe() const;
- const QWizard::WizardOption option;
- const bool on;
+ QWizard::WizardOption option;
+ bool on;
public:
- SetOption(QWizard::WizardOption option, bool on) : option(option), on(on) {}
+ static QSharedPointer<SetOption> create(QWizard::WizardOption option, bool on)
+ {
+ QSharedPointer<SetOption> o = QSharedPointer<SetOption>::create();
+ o->option = option;
+ o->on = on;
+ return o;
+ }
};
class OptionInfo
@@ -1660,16 +1676,16 @@ class OptionInfo
tags[QWizard::HaveCustomButton3] = "15/CB3";
for (int i = 0; i < 2; ++i) {
- QMap<QWizard::WizardOption, Operation *> operations_;
+ QMap<QWizard::WizardOption, QSharedPointer<Operation> > operations_;
foreach (QWizard::WizardOption option, tags.keys())
- operations_[option] = new SetOption(option, i == 1);
+ operations_[option] = SetOption::create(option, i == 1);
operations << operations_;
}
}
OptionInfo(OptionInfo const&);
OptionInfo& operator=(OptionInfo const&);
QMap<QWizard::WizardOption, QString> tags;
- QList<QMap<QWizard::WizardOption, Operation *> > operations;
+ QList<QMap<QWizard::WizardOption, QSharedPointer<Operation> > > operations;
public:
static OptionInfo &instance()
{
@@ -1678,7 +1694,7 @@ public:
}
QString tag(QWizard::WizardOption option) const { return tags.value(option); }
- Operation * operation(QWizard::WizardOption option, bool on) const
+ QSharedPointer<Operation> operation(QWizard::WizardOption option, bool on) const
{ return operations.at(on).value(option); }
QList<QWizard::WizardOption> options() const { return tags.keys(); }
};
@@ -1689,10 +1705,7 @@ QString SetOption::describe() const
+ QLatin1Char(on ? '1' : '0');
}
-Q_DECLARE_METATYPE(Operation *)
-Q_DECLARE_METATYPE(SetPage *)
-Q_DECLARE_METATYPE(SetStyle *)
-Q_DECLARE_METATYPE(SetOption *)
+Q_DECLARE_METATYPE(QVector<QSharedPointer<Operation> >)
class TestGroup
{
@@ -1709,14 +1722,17 @@ public:
combinations.clear();
}
- QList<Operation *> &add()
- { combinations << new QList<Operation *>; return *(combinations.last()); }
+ QVector<QSharedPointer<Operation> > &add()
+ {
+ combinations.resize(combinations.size() + 1);
+ return combinations.last();
+ }
void createTestRows()
{
for (int i = 0; i < combinations.count(); ++i) {
QTest::newRow((name.toLatin1() + ", row " + QByteArray::number(i)).constData())
- << (i == 0) << (type == Equality) << *(combinations.at(i));
+ << (i == 0) << (type == Equality) << combinations.at(i);
++nRows_;
}
}
@@ -1727,7 +1743,7 @@ private:
QString name;
Type type;
int nRows_;
- QList<QList<Operation *> *> combinations;
+ QVector<QVector<QSharedPointer<Operation> > > combinations;
};
class IntroPage : public QWizardPage
@@ -1811,9 +1827,9 @@ public:
}
}
- void applyOperations(const QList<Operation *> &operations)
+ void applyOperations(const QVector<QSharedPointer<Operation> > &operations)
{
- foreach (Operation * op, operations) {
+ foreach (const QSharedPointer<Operation> &op, operations) {
if (op) {
op->apply(this);
opsDescr += QLatin1Char('(') + op->describe() + QLatin1String(") ");
@@ -1833,31 +1849,29 @@ public:
class CombinationsTestData
{
TestGroup testGroup;
- QList<Operation *> pageOps;
- QList<Operation *> styleOps;
- QMap<bool, QList<Operation *> *> setAllOptions;
+ QVector<QSharedPointer<Operation> > pageOps;
+ QVector<QSharedPointer<Operation> > styleOps;
+ QMap<bool, QVector<QSharedPointer<Operation> > > setAllOptions;
public:
CombinationsTestData()
{
QTest::addColumn<bool>("ref");
QTest::addColumn<bool>("testEquality");
- QTest::addColumn<QList<Operation *> >("operations");
- pageOps << new SetPage(0) << new SetPage(1) << new SetPage(2);
- styleOps << new SetStyle(QWizard::ClassicStyle) << new SetStyle(QWizard::ModernStyle)
- << new SetStyle(QWizard::MacStyle);
+ QTest::addColumn<QVector<QSharedPointer<Operation> > >("operations");
+ pageOps << SetPage::create(0) << SetPage::create(1) << SetPage::create(2);
+ styleOps << SetStyle::create(QWizard::ClassicStyle) << SetStyle::create(QWizard::ModernStyle)
+ << SetStyle::create(QWizard::MacStyle);
#define SETPAGE(page) pageOps.at(page)
#define SETSTYLE(style) styleOps.at(style)
#define OPT(option, on) OptionInfo::instance().operation(option, on)
#define CLROPT(option) OPT(option, false)
#define SETOPT(option) OPT(option, true)
- setAllOptions[false] = new QList<Operation *>;
- setAllOptions[true] = new QList<Operation *>;
foreach (QWizard::WizardOption option, OptionInfo::instance().options()) {
- *setAllOptions.value(false) << CLROPT(option);
- *setAllOptions.value(true) << SETOPT(option);
+ setAllOptions[false] << CLROPT(option);
+ setAllOptions[true] << SETOPT(option);
}
-#define CLRALLOPTS *setAllOptions.value(false)
-#define SETALLOPTS *setAllOptions.value(true)
+#define CLRALLOPTS setAllOptions.value(false)
+#define SETALLOPTS setAllOptions.value(true)
}
int nRows() const { return testGroup.nRows(); }
@@ -1909,7 +1923,7 @@ public:
testGroup.createTestRows();
for (int i = 0; i < 2; ++i) {
- QList<Operation *> setOptions = *setAllOptions.value(i == 1);
+ QVector<QSharedPointer<Operation> > setOptions = setAllOptions.value(i == 1);
testGroup.reset("testAll 3.1");
testGroup.add() << setOptions;
@@ -1926,21 +1940,21 @@ public:
testGroup.createTestRows();
}
- foreach (Operation *pageOp, pageOps) {
+ foreach (const QSharedPointer<Operation> &pageOp, pageOps) {
testGroup.reset("testAll 4.1");
testGroup.add() << pageOp;
testGroup.add() << pageOp << pageOp;
testGroup.createTestRows();
for (int i = 0; i < 2; ++i) {
- QList<Operation *> optionOps = *setAllOptions.value(i == 1);
+ QVector<QSharedPointer<Operation> > optionOps = setAllOptions.value(i == 1);
testGroup.reset("testAll 4.2");
testGroup.add() << optionOps << pageOp;
testGroup.add() << pageOp << optionOps;
testGroup.createTestRows();
foreach (QWizard::WizardOption option, OptionInfo::instance().options()) {
- Operation *optionOp = OPT(option, i == 1);
+ QSharedPointer<Operation> optionOp = OPT(option, i == 1);
testGroup.reset("testAll 4.3");
testGroup.add() << optionOp << pageOp;
testGroup.add() << pageOp << optionOp;
@@ -1949,21 +1963,21 @@ public:
}
}
- foreach (Operation *styleOp, styleOps) {
+ foreach (const QSharedPointer<Operation> &styleOp, styleOps) {
testGroup.reset("testAll 5.1");
testGroup.add() << styleOp;
testGroup.add() << styleOp << styleOp;
testGroup.createTestRows();
for (int i = 0; i < 2; ++i) {
- QList<Operation *> optionOps = *setAllOptions.value(i == 1);
+ QVector<QSharedPointer<Operation> > optionOps = setAllOptions.value(i == 1);
testGroup.reset("testAll 5.2");
testGroup.add() << optionOps << styleOp;
testGroup.add() << styleOp << optionOps;
testGroup.createTestRows();
foreach (QWizard::WizardOption option, OptionInfo::instance().options()) {
- Operation *optionOp = OPT(option, i == 1);
+ QSharedPointer<Operation> optionOp = OPT(option, i == 1);
testGroup.reset("testAll 5.3");
testGroup.add() << optionOp << styleOp;
testGroup.add() << styleOp << optionOp;
@@ -1972,8 +1986,8 @@ public:
}
}
- foreach (Operation *pageOp, pageOps) {
- foreach (Operation *styleOp, styleOps) {
+ foreach (const QSharedPointer<Operation> &pageOp, pageOps) {
+ foreach (const QSharedPointer<Operation> &styleOp, styleOps) {
testGroup.reset("testAll 6.1");
testGroup.add() << pageOp;
@@ -1991,7 +2005,7 @@ public:
testGroup.createTestRows();
for (int i = 0; i < 2; ++i) {
- QList<Operation *> optionOps = *setAllOptions.value(i == 1);
+ QVector<QSharedPointer<Operation> > optionOps = setAllOptions.value(i == 1);
testGroup.reset("testAll 6.4");
testGroup.add() << optionOps << pageOp << styleOp;
testGroup.add() << pageOp << optionOps << styleOp;
@@ -2002,7 +2016,7 @@ public:
testGroup.createTestRows();
foreach (QWizard::WizardOption option, OptionInfo::instance().options()) {
- Operation *optionOp = OPT(option, i == 1);
+ QSharedPointer<Operation> optionOp = OPT(option, i == 1);
testGroup.reset("testAll 6.5");
testGroup.add() << optionOp << pageOp << styleOp;
testGroup.add() << pageOp << optionOp << styleOp;
@@ -2068,7 +2082,7 @@ void tst_QWizard::combinations()
QFETCH(bool, ref);
QFETCH(bool, testEquality);
- QFETCH(QList<Operation *>, operations);
+ QFETCH(QVector<QSharedPointer<Operation> >, operations);
TestWizard wizard;
#if !defined(QT_NO_STYLE_WINDOWSVISTA)
diff --git a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp
index dc527767a7..60dc7a7288 100644
--- a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp
+++ b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp
@@ -845,14 +845,14 @@ void tst_QGraphicsItem::parentItem()
void tst_QGraphicsItem::setParentItem()
{
QGraphicsScene scene;
- QGraphicsItem *item = scene.addRect(QRectF(0, 0, 10, 10));
+ const QScopedPointer<QGraphicsItem> item(scene.addRect(QRectF(0, 0, 10, 10)));
QCOMPARE(item->scene(), &scene);
- QGraphicsRectItem *child = new QGraphicsRectItem;
+ const QScopedPointer<QGraphicsRectItem> child(new QGraphicsRectItem);
QCOMPARE(child->scene(), (QGraphicsScene *)0);
// This implicitly adds the item to the parent's scene
- child->setParentItem(item);
+ child->setParentItem(item.data());
QCOMPARE(child->scene(), &scene);
// This just makes it a toplevel
@@ -860,8 +860,8 @@ void tst_QGraphicsItem::setParentItem()
QCOMPARE(child->scene(), &scene);
// Add the child back to the parent, then remove the parent from the scene
- child->setParentItem(item);
- scene.removeItem(item);
+ child->setParentItem(item.data());
+ scene.removeItem(item.data());
QCOMPARE(child->scene(), (QGraphicsScene *)0);
}
@@ -959,19 +959,19 @@ void tst_QGraphicsItem::flags()
QCOMPARE(item->pos(), QPointF(10, 10));
}
{
- QGraphicsItem* clippingParent = new QGraphicsRectItem;
+ const QScopedPointer<QGraphicsItem> clippingParent(new QGraphicsRectItem);
clippingParent->setFlag(QGraphicsItem::ItemClipsChildrenToShape, true);
- QGraphicsItem* nonClippingParent = new QGraphicsRectItem;
+ const QScopedPointer<QGraphicsItem> nonClippingParent(new QGraphicsRectItem);
nonClippingParent->setFlag(QGraphicsItem::ItemClipsChildrenToShape, false);
- QGraphicsItem* child = new QGraphicsRectItem(nonClippingParent);
+ QGraphicsItem* child = new QGraphicsRectItem(nonClippingParent.data());
QVERIFY(!child->isClipped());
- child->setParentItem(clippingParent);
+ child->setParentItem(clippingParent.data());
QVERIFY(child->isClipped());
- child->setParentItem(nonClippingParent);
+ child->setParentItem(nonClippingParent.data());
QVERIFY(!child->isClipped());
}
}
@@ -3130,7 +3130,8 @@ void tst_QGraphicsItem::isAncestorOf()
void tst_QGraphicsItem::commonAncestorItem()
{
- QGraphicsItem *ancestor = new QGraphicsRectItem;
+ QGraphicsRectItem ancestorItem;
+ QGraphicsItem *ancestor = &ancestorItem;
QGraphicsItem *grandMa = new QGraphicsRectItem;
QGraphicsItem *grandPa = new QGraphicsRectItem;
QGraphicsItem *brotherInLaw = new QGraphicsRectItem;
@@ -3630,7 +3631,7 @@ void tst_QGraphicsItem::setGroup()
QGraphicsItemGroup group1;
QGraphicsItemGroup group2;
- QGraphicsRectItem *rect = new QGraphicsRectItem;
+ const QScopedPointer<QGraphicsRectItem> rect(new QGraphicsRectItem);
QCOMPARE(rect->group(), (QGraphicsItemGroup *)0);
QCOMPARE(rect->parentItem(), (QGraphicsItem *)0);
rect->setGroup(&group1);
@@ -6835,8 +6836,8 @@ void tst_QGraphicsItem::opacity()
QFETCH(qreal, c2_effectiveOpacity);
QFETCH(qreal, c3_effectiveOpacity);
- QGraphicsRectItem *p = new QGraphicsRectItem;
- QGraphicsRectItem *c1 = new QGraphicsRectItem(p);
+ const QScopedPointer<QGraphicsRectItem> p(new QGraphicsRectItem);
+ QGraphicsRectItem *c1 = new QGraphicsRectItem(p.data());
QGraphicsRectItem *c2 = new QGraphicsRectItem(c1);
QGraphicsRectItem *c3 = new QGraphicsRectItem(c2);
@@ -7224,11 +7225,12 @@ void tst_QGraphicsItem::sceneTransformCache()
// Test that an item's scene transform is updated correctly when the
// parent is transformed.
QGraphicsScene scene;
- QGraphicsRectItem *rect = scene.addRect(0, 0, 100, 100);
+
+ const QScopedPointer<QGraphicsRectItem> rect(scene.addRect(0, 0, 100, 100));
rect->setPen(QPen(Qt::black, 0));
QGraphicsRectItem *rect2 = scene.addRect(0, 0, 100, 100);
rect2->setPen(QPen(Qt::black, 0));
- rect2->setParentItem(rect);
+ rect2->setParentItem(rect.data());
rect2->setTransform(QTransform().rotate(90), true);
rect->setTransform(QTransform::fromTranslate(0, 50), true);
QGraphicsView view(&scene);
@@ -7240,7 +7242,7 @@ void tst_QGraphicsItem::sceneTransformCache()
x.rotate(90);
QCOMPARE(rect2->sceneTransform(), x);
- scene.removeItem(rect);
+ scene.removeItem(rect.data());
//Crazy use case : rect4 child of rect3 so the transformation of rect4 will be cached.Good!
//We remove rect4 from the scene, then the validTransform bit flag is set to 0 and the index of the cache
@@ -10696,7 +10698,7 @@ void tst_QGraphicsItem::scenePosChange()
{
ScenePosChangeTester* root = new ScenePosChangeTester;
ScenePosChangeTester* child1 = new ScenePosChangeTester(root);
- ScenePosChangeTester* grandChild1 = new ScenePosChangeTester(child1);
+ const QScopedPointer<ScenePosChangeTester> grandChild1(new ScenePosChangeTester(child1));
ScenePosChangeTester* child2 = new ScenePosChangeTester(root);
ScenePosChangeTester* grandChild2 = new ScenePosChangeTester(child2);
@@ -10748,7 +10750,7 @@ void tst_QGraphicsItem::scenePosChange()
QCOMPARE(grandChild2->changes.count(QGraphicsItem::ItemScenePositionHasChanged), 3);
// remove
- scene.removeItem(grandChild1);
+ scene.removeItem(grandChild1.data());
delete grandChild2; grandChild2 = 0;
QCoreApplication::processEvents(); // QGraphicsScenePrivate::_q_updateScenePosDescendants()
root->moveBy(1.0, 1.0);
diff --git a/tests/auto/widgets/widgets/qmenubar/qmenubar.pro b/tests/auto/widgets/widgets/qmenubar/qmenubar.pro
index 3fb6ae61a8..e680cf4d7d 100644
--- a/tests/auto/widgets/widgets/qmenubar/qmenubar.pro
+++ b/tests/auto/widgets/widgets/qmenubar/qmenubar.pro
@@ -2,3 +2,8 @@ CONFIG += testcase
TARGET = tst_qmenubar
QT += widgets testlib
SOURCES += tst_qmenubar.cpp
+
+macos: {
+ OBJECTIVE_SOURCES += tst_qmenubar_mac.mm
+ LIBS += -framework AppKit
+}
diff --git a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp
index 185bfc02a0..9a68655fb6 100644
--- a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp
+++ b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp
@@ -130,6 +130,9 @@ private slots:
void cornerWidgets_data();
void cornerWidgets();
void taskQTBUG53205_crashReparentNested();
+#ifdef Q_OS_MACOS
+ void taskQTBUG56275_reinsertMenuInParentlessQMenuBar();
+#endif
protected slots:
void onSimpleActivated( QAction*);
@@ -1496,7 +1499,28 @@ void tst_QMenuBar::slotForTaskQTBUG53205()
taskQTBUG53205MenuBar->setParent(parent);
}
+#ifdef Q_OS_MACOS
+extern bool tst_qmenubar_taskQTBUG56275(QMenuBar *);
+
+void tst_QMenuBar::taskQTBUG56275_reinsertMenuInParentlessQMenuBar()
+{
+ QMenuBar menubar;
+ QMenu *menu = new QMenu("menu", &menubar);
+ QMenu* submenu = menu->addMenu("submenu");
+ submenu->addAction("action1");
+ submenu->addAction("action2");
+ menu->addAction("action3");
+ menubar.addMenu(menu);
+
+ QTest::qWait(100);
+ menubar.clear();
+ menubar.addMenu(menu);
+ QTest::qWait(100);
+
+ QVERIFY(tst_qmenubar_taskQTBUG56275(&menubar));
+}
+#endif // Q_OS_MACOS
QTEST_MAIN(tst_QMenuBar)
#include "tst_qmenubar.moc"
diff --git a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar_mac.mm b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar_mac.mm
new file mode 100644
index 0000000000..4645de4d7a
--- /dev/null
+++ b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar_mac.mm
@@ -0,0 +1,44 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the test suite 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 <Cocoa/Cocoa.h>
+
+#include <QMenuBar>
+#include <QTest>
+
+bool tst_qmenubar_taskQTBUG56275(QMenuBar *menubar)
+{
+ NSMenu *mainMenu = menubar->toNSMenu();
+ return mainMenu.numberOfItems == 2
+ && [[mainMenu itemAtIndex:1].title isEqualToString:@"menu"];
+}