From 76359dab8ea88403def4ad11e884080d3eb03e3e Mon Sep 17 00:00:00 2001 From: Thomas Senyk Date: Wed, 25 Sep 2013 13:22:55 +0200 Subject: eglfs/imx6: enable double buffering and vsync by default Enabling vsync and double buffering improves the overall impression. Enabling by default helps to get the best "out of the box" If not desired, one can disable this behavior via: export QT_EGLFS_IMX6_NO_FB_MULTI_BUFFER=1 Change-Id: I21ce5366ea5829140d8103cf2dbd8c487d079db6 Reviewed-by: Donald Carr Reviewed-by: Gunnar Sletta --- mkspecs/devices/linux-imx6-g++/qeglfshooks_imx6.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/mkspecs/devices/linux-imx6-g++/qeglfshooks_imx6.cpp b/mkspecs/devices/linux-imx6-g++/qeglfshooks_imx6.cpp index 2a5ee74648..c351e3dbc4 100644 --- a/mkspecs/devices/linux-imx6-g++/qeglfshooks_imx6.cpp +++ b/mkspecs/devices/linux-imx6-g++/qeglfshooks_imx6.cpp @@ -41,6 +41,7 @@ #include "qeglfshooks.h" #include +#include QT_BEGIN_NAMESPACE @@ -62,6 +63,15 @@ private: QEglFSImx6Hooks::QEglFSImx6Hooks() { int width, height; + + bool multiBufferNotEnabledYet = qEnvironmentVariableIsEmpty("FB_MULTI_BUFFER"); + bool multiBuffer = qEnvironmentVariableIsEmpty("QT_EGLFS_IMX6_NO_FB_MULTI_BUFFER"); + if (multiBufferNotEnabledYet && multiBuffer) { + qWarning() << "QEglFSImx6Hooks will set environment variable FB_MULTI_BUFFER=2 to enable double buffering and vsync.\n" + << "If this is not desired, you can override this via: export QT_EGLFS_IMX6_NO_FB_MULTI_BUFFER=1"; + qputenv("FB_MULTI_BUFFER", "2"); + } + mNativeDisplay = fbGetDisplayByIndex(0); fbGetDisplayGeometry(mNativeDisplay, &width, &height); mScreenSize.setHeight(height); -- cgit v1.2.3 From 8e7dc25380dceebca094e092d9feb21ad167ba91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 9 Oct 2013 16:26:44 +0200 Subject: qmake: Load extra variables only if also loading pre-files The extra variables only need to be applied once, when we are loading the pro file (and hence are loding pre files), not for every single pri/prf that's loaded as a result of that (which do not load pre files themselves). Change-Id: I3118694a8eeccf2dc32c4f62df754033fad13528 Reviewed-by: Oswald Buddenhagen --- qmake/library/qmakeevaluator.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/qmake/library/qmakeevaluator.cpp b/qmake/library/qmakeevaluator.cpp index 9bf870ce39..c4b8c150e7 100644 --- a/qmake/library/qmakeevaluator.cpp +++ b/qmake/library/qmakeevaluator.cpp @@ -1365,10 +1365,6 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProFile( loadDefaults(); } - for (ProValueMap::ConstIterator it = m_extraVars.constBegin(); - it != m_extraVars.constEnd(); ++it) - m_valuemapStack.first().insert(it.key(), it.value()); - VisitReturn vr; m_handler->aboutToEval(currentProFile(), pro, type); @@ -1377,6 +1373,10 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProFile( if (flags & LoadPreFiles) { setupProject(); + for (ProValueMap::ConstIterator it = m_extraVars.constBegin(); + it != m_extraVars.constEnd(); ++it) + m_valuemapStack.first().insert(it.key(), it.value()); + if ((vr = evaluateFeatureFile(QLatin1String("default_pre.prf"))) == ReturnError) goto failed; -- cgit v1.2.3 From eea1c359c9663cec15e7373c065ee06cba151eed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 8 Oct 2013 23:44:24 +0200 Subject: qmake: Evaluate extra configs before loading default_pre Exclusive builds uses setExtraConfigs to apply the particular CONFIG of each build pass. Unfortunately we were not applying these extra configs early enough in QMakeEvaluator::visitProFile() for them to be picked up/usable by default_pre, something that can be useful. Change-Id: I423a4688250a15f0c1a2cc65a48f0bbc14ad4497 Reviewed-by: Oswald Buddenhagen --- qmake/library/qmakeevaluator.cpp | 24 ++++++++++++++++++------ qmake/library/qmakeevaluator.h | 1 + 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/qmake/library/qmakeevaluator.cpp b/qmake/library/qmakeevaluator.cpp index c4b8c150e7..9a2bcd7680 100644 --- a/qmake/library/qmakeevaluator.cpp +++ b/qmake/library/qmakeevaluator.cpp @@ -1271,6 +1271,14 @@ void QMakeEvaluator::evaluateCommand(const QString &cmds, const QString &where) } } +void QMakeEvaluator::applyExtraConfigs() +{ + if (m_extraConfigs.isEmpty()) + return; + + evaluateCommand(fL1S("CONFIG += ") + m_extraConfigs.join(QLatin1Char(' ')), fL1S("(extra configs)")); +} + QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateConfigFeatures() { QSet processed; @@ -1377,14 +1385,19 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProFile( it != m_extraVars.constEnd(); ++it) m_valuemapStack.first().insert(it.key(), it.value()); + // In case default_pre needs to make decisions based on the current + // build pass configuration. + applyExtraConfigs(); + if ((vr = evaluateFeatureFile(QLatin1String("default_pre.prf"))) == ReturnError) goto failed; - evaluateCommand(m_option->precmds, fL1S("(command line)")); + if (!m_option->precmds.isEmpty()) { + evaluateCommand(m_option->precmds, fL1S("(command line)")); - // After user configs, to override them - if (!m_extraConfigs.isEmpty()) - evaluateCommand(fL1S("CONFIG += ") + m_extraConfigs.join(QLatin1Char(' ')), fL1S("(extra configs)")); + // Again, after user configs, to override them + applyExtraConfigs(); + } } debugMsg(1, "visiting file %s", qPrintable(pro->fileName())); @@ -1398,8 +1411,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProFile( // Again, to ensure the project does not mess with us. // Specifically, do not allow a project to override debug/release within a // debug_and_release build pass - it's too late for that at this point anyway. - if (!m_extraConfigs.isEmpty()) - evaluateCommand(fL1S("CONFIG += ") + m_extraConfigs.join(QLatin1Char(' ')), fL1S("(extra configs)")); + applyExtraConfigs(); if ((vr = evaluateFeatureFile(QLatin1String("default_post.prf"))) == ReturnError) goto failed; diff --git a/qmake/library/qmakeevaluator.h b/qmake/library/qmakeevaluator.h index 8ca2b182c7..c1e7037762 100644 --- a/qmake/library/qmakeevaluator.h +++ b/qmake/library/qmakeevaluator.h @@ -170,6 +170,7 @@ public: void initFrom(const QMakeEvaluator &other); void setupProject(); void evaluateCommand(const QString &cmds, const QString &where); + void applyExtraConfigs(); VisitReturn visitProFile(ProFile *pro, QMakeHandler::EvalFileType type, LoadFlags flags); VisitReturn visitProBlock(ProFile *pro, const ushort *tokPtr); -- cgit v1.2.3 From 5e4b9f11543e8573cd3bbe9cad83274d44ce74a3 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 11 Oct 2013 15:29:51 +0200 Subject: Use QAtomicInt ref/deref pattern Change check of QAtomicInt::load with the preferred ref() deref() pattern. Change-Id: I12d2e24812259c16623c8a59cac30cafa4b05565 Reviewed-by: Konstantin Ritt --- src/gui/text/qtextengine.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index c0e2c5b803..2b0f9ffeb6 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -1883,11 +1883,12 @@ QFontEngine *QTextEngine::fontEngine(const QScriptItem &si, QFixed *ascent, QFix scaledEngine = feCache.prevScaledFontEngine; } else { QFontEngine *scEngine = rawFont.d->fontEngine->cloneWithSize(smallCapsFraction * rawFont.pixelSize()); + scEngine->ref.ref(); scaledEngine = QFontEngineMultiQPA::createMultiFontEngine(scEngine, script); scaledEngine->ref.ref(); feCache.prevScaledFontEngine = scaledEngine; // If scEngine is not ref'ed by scaledEngine, make sure it is deallocated and not leaked. - if (!scEngine->ref.load()) + if (!scEngine->ref.deref()) delete scEngine; } -- cgit v1.2.3 From 9e7fa9f72b0f83bff77fffe127bd3b34a8f54aa7 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 4 Oct 2013 16:44:42 +0200 Subject: Make QSystemTrayIcon::showMessage invokable Qt WebKit's HTML5 web notifications rely on QSystemTrayIcon::showMessage to be invokable since the lower WebCore components can not link directly to QWidgets. Change-Id: I952de47ed8a90553a8f1ac30256d77ef6014da44 Reviewed-by: Friedemann Kleint Reviewed-by: Simon Hausmann --- src/widgets/util/qsystemtrayicon.cpp | 2 ++ src/widgets/util/qsystemtrayicon.h | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/widgets/util/qsystemtrayicon.cpp b/src/widgets/util/qsystemtrayicon.cpp index 08b24a8200..79ca0a5bdb 100644 --- a/src/widgets/util/qsystemtrayicon.cpp +++ b/src/widgets/util/qsystemtrayicon.cpp @@ -380,6 +380,8 @@ bool QSystemTrayIcon::supportsMessages() On Mac OS X, the Growl notification system must be installed for this function to display messages. + Has been turned into a slot in Qt 5.2. + \sa show(), supportsMessages() */ void QSystemTrayIcon::showMessage(const QString& title, const QString& msg, diff --git a/src/widgets/util/qsystemtrayicon.h b/src/widgets/util/qsystemtrayicon.h index 278efae586..d6ba553a3a 100644 --- a/src/widgets/util/qsystemtrayicon.h +++ b/src/widgets/util/qsystemtrayicon.h @@ -94,8 +94,6 @@ public: static bool supportsMessages(); enum MessageIcon { NoIcon, Information, Warning, Critical }; - void showMessage(const QString &title, const QString &msg, - MessageIcon icon = Information, int msecs = 10000); QRect geometry() const; bool isVisible() const; @@ -104,6 +102,8 @@ public Q_SLOTS: void setVisible(bool visible); inline void show() { setVisible(true); } inline void hide() { setVisible(false); } + void showMessage(const QString &title, const QString &msg, + QSystemTrayIcon::MessageIcon icon = QSystemTrayIcon::Information, int msecs = 10000); Q_SIGNALS: void activated(QSystemTrayIcon::ActivationReason reason); -- cgit v1.2.3 From 46cde99c57f33136ed98e3e0d441c68b73a798dc Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Fri, 11 Oct 2013 10:39:15 +0200 Subject: add a missing break in QGuiApplicationPrivate::processWindowSystemEvent Task-number: QTBUG-34016 Change-Id: Ifbb4a63845328e32fb0ad679415dca0f90dde624 Reviewed-by: Andy Shaw --- src/gui/kernel/qguiapplication.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 47efc98474..542b95f58f 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -1489,6 +1489,7 @@ void QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePriv #endif case QWindowSystemInterfacePrivate::EnterWhatsThisMode: QGuiApplication::postEvent(QGuiApplication::instance(), new QEvent(QEvent::EnterWhatsThisMode)); + break; default: qWarning() << "Unknown user input event type:" << e->type; break; -- cgit v1.2.3 From 65855d9d68255a50d5f1336c7b9be1f079bf3cc5 Mon Sep 17 00:00:00 2001 From: Sergio Ahumada Date: Wed, 9 Oct 2013 12:51:48 +0200 Subject: iOS: Skip qtmacextras module This module doesn't make much sense for iOS. Change-Id: Iadcf3006e1e2bdd97c460e836e91717856cb118c Reviewed-by: Thiago Macieira Reviewed-by: Iikka Eklund --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index 83bbf725af..dd2c01c3a4 100755 --- a/configure +++ b/configure @@ -2882,7 +2882,7 @@ if [ "$XPLATFORM_IOS" = "yes" ]; then CFG_NOBUILD_PARTS="$CFG_NOBUILD_PARTS examples tests" CFG_SHARED="no" # iOS builds should be static to be able to submit to the App Store CFG_CXX11="no" # C++11 support disabled for now - CFG_SKIP_MODULES="$CFG_SKIP_MODULES qtconnectivity qtdoc qtgraphicaleffects qtlocation qtmultimedia qtquickcontrols qtserialport qttools qtwebkit qtwebkit-examples" + CFG_SKIP_MODULES="$CFG_SKIP_MODULES qtconnectivity qtdoc qtgraphicaleffects qtlocation qtmacextras qtmultimedia qtquickcontrols qtserialport qttools qtwebkit qtwebkit-examples" fi # disable GTK style support auto-detection on Mac -- cgit v1.2.3 From 2b8e571f8458a533d1b902fff5a812db427b7da0 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 10 Oct 2013 13:57:57 +0200 Subject: Stabilize tst_QComboBox::keyBoardNavigationWithMouse. The cursor needs to be within the view from start on Mac. Task-number: QTBUG-33973 Change-Id: I313c9fd1c3a917e135a92497f1818d1b0d8b7698 Reviewed-by: Gabriel de Dietrich --- .../auto/widgets/widgets/qcombobox/tst_qcombobox.cpp | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp index 4631154230..eabb7aaa17 100644 --- a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp +++ b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp @@ -2587,6 +2587,18 @@ void tst_QComboBox::resetModel() } +static inline void centerCursor(const QWidget *w) +{ +#ifndef QT_NO_CURSOR + // Force cursor movement to prevent QCursor::setPos() from returning prematurely on QPA: + const QPoint target(w->mapToGlobal(w->rect().center())); + QCursor::setPos(QPoint(target.x() + 1, target.y())); + QCursor::setPos(target); +#else // !QT_NO_CURSOR + Q_UNUSED(w) +#endif +} + void tst_QComboBox::keyBoardNavigationWithMouse() { QComboBox combo; @@ -2597,6 +2609,7 @@ void tst_QComboBox::keyBoardNavigationWithMouse() combo.addItem( QString::number(i)); combo.show(); + centerCursor(&combo); // QTBUG-33973, cursor needs to be within view from start on Mac. QApplication::setActiveWindow(&combo); QVERIFY(QTest::qWaitForWindowActive(&combo)); QCOMPARE(QApplication::activeWindow(), static_cast(&combo)); @@ -2617,10 +2630,7 @@ void tst_QComboBox::keyBoardNavigationWithMouse() // When calling cursor function, Windows CE responds with: This function is not supported on this system. #ifndef Q_OS_WINCE // Force cursor movement to prevent QCursor::setPos() from returning prematurely on QPA: - const QPoint target(combo.view()->mapToGlobal(combo.view()->rect().center())); - QCursor::setPos(QPoint(target.x() + 1, target.y())); - QCursor::setPos(target); - + centerCursor(combo.view()); QTest::qWait(200); #define GET_SELECTION(SEL) \ @@ -2632,7 +2642,7 @@ void tst_QComboBox::keyBoardNavigationWithMouse() GET_SELECTION(selection); //since we moved the mouse is in the middle it should even be around 5; - QVERIFY(selection > 3); + QVERIFY2(selection > 3, (QByteArrayLiteral("selection=") + QByteArray::number(selection)).constData()); static const int final = 40; for (int i = selection + 1; i <= final; i++) -- cgit v1.2.3 From 0e96e47debd1d8c48d1d23fd51c9ee05f61c80e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 7 Oct 2013 17:55:45 +0200 Subject: qmake: Centralize TARGET sanitization in default_post.prf MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Shared between UNIX and Win generators, and allows prfs after default_post to rely on sane TARGET and DESTDIR values. This allows us to clean up the DESTDIR logic in testcase.prf, which was completely busted. Doing the two in separate commits is unfortunately not possible as the old testcase.prf logic was so broken it would barf if only looked at. Change-Id: Ibf21216195c760ee46ae679c162b207b77a9d813 Reviewed-by: Jan Arve Sæther Reviewed-by: Tor Arne Vestbø Reviewed-by: Oswald Buddenhagen --- mkspecs/features/default_post.prf | 12 +++++++++ mkspecs/features/testcase.prf | 45 +++++++++++++++++----------------- qmake/generators/unix/unixmake.cpp | 14 +---------- qmake/generators/win32/winmakefile.cpp | 14 ----------- 4 files changed, 36 insertions(+), 49 deletions(-) diff --git a/mkspecs/features/default_post.prf b/mkspecs/features/default_post.prf index c756455dd2..4501b2a568 100644 --- a/mkspecs/features/default_post.prf +++ b/mkspecs/features/default_post.prf @@ -6,6 +6,18 @@ contains(TEMPLATE, ".*(lib|app)"):CONFIG += have_target load(resolve_config) +# If the TARGET looks like a path, split it into DESTDIR and the resulting TARGET +target_dir_part = $$dirname(TARGET) +!isEmpty(target_dir_part) { + isEmpty(DESTDIR): \ + DESTDIR = $$target_dir_part + else: \ + DESTDIR = $$DESTDIR/$$target_dir_part + + TARGET = $$basename(TARGET) + DESTDIR = $$clean_path($$DESTDIR) +} + QT_BREAKPAD_ROOT_PATH = $$(QT_BREAKPAD_ROOT_PATH) !isEmpty(QT_BREAKPAD_ROOT_PATH): \ # quick test first whether requested ... !static:release:have_target: \ # is it applicable? diff --git a/mkspecs/features/testcase.prf b/mkspecs/features/testcase.prf index e31d1f4539..10f421a8e2 100644 --- a/mkspecs/features/testcase.prf +++ b/mkspecs/features/testcase.prf @@ -10,34 +10,35 @@ check.files = check.path = . # If the test ends up in a different directory, we should cd to that directory. -# Note that qmake modifies DESTDIR after this file is processed, -# therefore, testing DESTDIR for emptiness is not sufficient. -# Also note that in debug-and-release mode we don't want to cd into the debug/release -# directory (e.g. if the test goes to foo/release/tst_thing.exe, we want to do -# cd foo && release/tst_thing.exe ). -MUNGED_DESTDIR=$$DESTDIR -MUNGED_TARGET=$$TARGET -win32:debug_and_release { - contains(DESTDIR,^release$)|contains(DESTDIR,^debug$):MUNGED_DESTDIR= - - # In debug-and-release mode, the first ../ in TARGET breaks out of the debug/release - # subdirectory. However, since make's working directory is already outside of the - # debug/release subdirectory, this first ../ should be ignored when deciding if - # we have to change directory before running the test. - MUNGED_TARGET=$$replace(MUNGED_TARGET,^\\.\\./,) +TESTRUN_CWD = $$DESTDIR + +debug_and_release:debug_and_release_target { + # But in debug-and-release-target mode we don't want to cd into the debug/release + # directory (e.g. if the test goes to foo/release/tst_thing.exe, we want to do + # 'cd foo && release/tst_thing.exe', not 'cd foo/release && tst_thing.exe'). + + TESTRUN_CWD ~= s/(release|debug)$// + TEST_TARGET_DIR = $$relative_path($$absolute_path($$DESTDIR, $$OUT_PWD), $$absolute_path($$TESTRUN_CWD, $$OUT_PWD)) } -!isEmpty(MUNGED_DESTDIR):!contains(MUNGED_DESTDIR,^\\./?):check.commands = cd $(DESTDIR) && -contains(MUNGED_TARGET,.*/.*):check.commands = cd $(DESTDIR) && + +!isEmpty(TESTRUN_CWD):!contains(TESTRUN_CWD,^\\./?): \ + check.commands = cd $$system_path($$TESTRUN_CWD) && # Allow for a custom test runner script check.commands += $(TESTRUNNER) -mac { - app_bundle: check.commands += ./$(QMAKE_TARGET).app/Contents/MacOS/$(QMAKE_TARGET) - else: check.commands += ./$(QMAKE_TARGET) +unix { + isEmpty(TEST_TARGET_DIR): TEST_TARGET_DIR = . + + mac:app_bundle: \ + check.commands += $${TEST_TARGET_DIR}/$(QMAKE_TARGET).app/Contents/MacOS/$(QMAKE_TARGET) + else: \ + check.commands += $${TEST_TARGET_DIR}/$(QMAKE_TARGET) +} else { + # Windows + !isEmpty(TEST_TARGET_DIR): TEST_TARGET_DIR = $${TEST_TARGET_DIR}$${QMAKE_DIR_SEP} + check.commands += $${TEST_TARGET_DIR}$(TARGET) } -else:unix: check.commands += ./$(QMAKE_TARGET) -else: check.commands += $(DESTDIR_TARGET) # Allow for custom arguments to tests check.commands += $(TESTARGS) diff --git a/qmake/generators/unix/unixmake.cpp b/qmake/generators/unix/unixmake.cpp index adeb55af86..1c95392932 100644 --- a/qmake/generators/unix/unixmake.cpp +++ b/qmake/generators/unix/unixmake.cpp @@ -106,20 +106,8 @@ UnixMakefileGenerator::init() return; /* subdirs is done */ } - //If the TARGET looks like a path split it into DESTDIR and the resulting TARGET - if(!project->isEmpty("TARGET")) { + if (!project->isEmpty("TARGET")) project->values("TARGET") = escapeFilePaths(project->values("TARGET")); - ProString targ = unescapeFilePath(project->first("TARGET")); - int slsh = qMax(targ.lastIndexOf('/'), targ.lastIndexOf(Option::dir_sep)); - if(slsh != -1) { - if(project->isEmpty("DESTDIR")) - project->values("DESTDIR").append(""); - else if(project->first("DESTDIR").right(1) != Option::dir_sep) - project->values("DESTDIR") = ProStringList(project->first("DESTDIR") + Option::dir_sep); - project->values("DESTDIR") = ProStringList(project->first("DESTDIR") + targ.left(slsh+1)); - project->values("TARGET") = ProStringList(targ.mid(slsh+1)); - } - } project->values("QMAKE_ORIG_TARGET") = project->values("TARGET"); project->values("QMAKE_ORIG_DESTDIR") = project->values("DESTDIR"); diff --git a/qmake/generators/win32/winmakefile.cpp b/qmake/generators/win32/winmakefile.cpp index 2ef2d82b5a..0ad0f09bce 100644 --- a/qmake/generators/win32/winmakefile.cpp +++ b/qmake/generators/win32/winmakefile.cpp @@ -274,20 +274,6 @@ Win32MakefileGenerator::processPrlFiles() void Win32MakefileGenerator::processVars() { - //If the TARGET looks like a path split it into DESTDIR and the resulting TARGET - if(!project->isEmpty("TARGET")) { - ProString targ = project->first("TARGET"); - int slsh = qMax(targ.lastIndexOf('/'), targ.lastIndexOf(Option::dir_sep)); - if(slsh != -1) { - if(project->isEmpty("DESTDIR")) - project->values("DESTDIR").append(""); - else if(project->first("DESTDIR").right(1) != Option::dir_sep) - project->values("DESTDIR") = ProStringList(project->first("DESTDIR") + Option::dir_sep); - project->values("DESTDIR") = ProStringList(project->first("DESTDIR") + targ.left(slsh+1)); - project->values("TARGET") = ProStringList(targ.mid(slsh+1)); - } - } - project->values("QMAKE_ORIG_TARGET") = project->values("TARGET"); if (project->isEmpty("QMAKE_PROJECT_NAME")) project->values("QMAKE_PROJECT_NAME") = project->values("QMAKE_ORIG_TARGET"); -- cgit v1.2.3 From 059857d4d5dc5862d0135c839e7dabaa7331e4b5 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 5 Oct 2013 03:48:45 +0200 Subject: QVector: add some functions missing for QList compat Eases migration from QList to QVector. Had to rename the 'length' parameter to mid() to suppress -Wshadow warnings. Task-number: QTBUG-3781 Change-Id: I755c6caefe4de81ea42a81b1c76aab728e639613 Reviewed-by: Lars Knoll --- src/corelib/tools/qvector.cpp | 38 ++++++++++++++++++++++++++++++++++++++ src/corelib/tools/qvector.h | 23 ++++++++++++++--------- 2 files changed, 52 insertions(+), 9 deletions(-) diff --git a/src/corelib/tools/qvector.cpp b/src/corelib/tools/qvector.cpp index 69b656c191..11990d30b2 100644 --- a/src/corelib/tools/qvector.cpp +++ b/src/corelib/tools/qvector.cpp @@ -562,6 +562,44 @@ \sa insert(), replace(), fill() */ +/*! \fn void QVector::removeAt(int i) + \since 5.2 + + Equivalent to + \code + remove(i); + \endcode + + Provided for compatibility with QList. + + \sa remove(int), QList::removeAt(int) +*/ + +/*! \fn int QVector::length() const + \since 5.2 + + Same as size() and count(). + + Provided for compatibility with QList. + + \sa size(), count(), QList::length() +*/ + +/*! \fn T QVector::takeAt(int i) + \since 5.2 + + Equivalent to + \code + T t = at(i); + remove(i); + return t; + \endcode + + Provided for compatibility with QList. + + \sa takeFirst(), takeLast(), QList::takeAt(int) +*/ + /*! \fn void QVector::removeFirst() \since 5.1 Removes the first item in the vector. Calling this function is diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h index 3d86440fcd..f56511edbf 100644 --- a/src/corelib/tools/qvector.h +++ b/src/corelib/tools/qvector.h @@ -152,6 +152,11 @@ public: bool contains(const T &t) const; int count(const T &t) const; + // QList compatibility + void removeAt(int i) { remove(i); } + int length() const { return size(); } + T takeAt(int i) { T t = at(i); remove(i); return t; } + // STL-style typedef typename Data::iterator iterator; typedef typename Data::const_iterator const_iterator; @@ -187,7 +192,7 @@ public: inline const T &last() const { Q_ASSERT(!isEmpty()); return *(end()-1); } inline bool startsWith(const T &t) const { return !isEmpty() && first() == t; } inline bool endsWith(const T &t) const { return !isEmpty() && last() == t; } - QVector mid(int pos, int length = -1) const; + QVector mid(int pos, int len = -1) const; T value(int i) const; T value(int i, const T &defaultValue) const; @@ -772,17 +777,17 @@ int QVector::count(const T &t) const } template -Q_OUTOFLINE_TEMPLATE QVector QVector::mid(int pos, int length) const +Q_OUTOFLINE_TEMPLATE QVector QVector::mid(int pos, int len) const { - if (length < 0) - length = size() - pos; - if (pos == 0 && length == size()) + if (len < 0) + len = size() - pos; + if (pos == 0 && len == size()) return *this; - if (pos + length > size()) - length = size() - pos; + if (pos + len > size()) + len = size() - pos; QVector copy; - copy.reserve(length); - for (int i = pos; i < pos + length; ++i) + copy.reserve(len); + for (int i = pos; i < pos + len; ++i) copy += at(i); return copy; } -- cgit v1.2.3 From d8d6880682c8d3ad52a2b5e5670560dca399d854 Mon Sep 17 00:00:00 2001 From: Kevin Ottens Date: Wed, 9 Oct 2013 13:12:11 +0200 Subject: Reduce risks of lock file corruption MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Trying to do as few operations as possible once the file got opened. That includes generating the data which will go in the file. Indeed if we crashed at that point the lock file is already emptied. Could happen because of the qAppName call. It's then safer to prepare the data upfront, and just open/write/close if possible. Change-Id: Iad32fa822c6a5958ae89d84a2fe02ed5366ea278 Reviewed-by: Jędrzej Nowacki Reviewed-by: Frederik Gladhorn --- src/corelib/io/qlockfile_unix.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/corelib/io/qlockfile_unix.cpp b/src/corelib/io/qlockfile_unix.cpp index 1676b71133..de21ee217a 100644 --- a/src/corelib/io/qlockfile_unix.cpp +++ b/src/corelib/io/qlockfile_unix.cpp @@ -140,6 +140,16 @@ static bool setNativeLocks(int fd) QLockFile::LockError QLockFilePrivate::tryLock_sys() { + // Assemble data, to write in a single call to write + // (otherwise we'd have to check every write call) + QByteArray fileData; + fileData += QByteArray::number(QCoreApplication::applicationPid()); + fileData += '\n'; + fileData += qAppName().toUtf8(); + fileData += '\n'; + fileData += localHostName().toUtf8(); + fileData += '\n'; + const QByteArray lockFileName = QFile::encodeName(fileName); const int fd = qt_safe_open(lockFileName.constData(), O_WRONLY | O_CREAT | O_EXCL, 0644); if (fd < 0) { @@ -160,16 +170,6 @@ QLockFile::LockError QLockFilePrivate::tryLock_sys() // We hold the lock, continue. fileHandle = fd; - // Assemble data, to write in a single call to write - // (otherwise we'd have to check every write call) - QByteArray fileData; - fileData += QByteArray::number(QCoreApplication::applicationPid()); - fileData += '\n'; - fileData += qAppName().toUtf8(); - fileData += '\n'; - fileData += localHostName().toUtf8(); - fileData += '\n'; - QLockFile::LockError error = QLockFile::NoError; if (qt_write_loop(fd, fileData.constData(), fileData.size()) < fileData.size()) error = QLockFile::UnknownError; // partition full -- cgit v1.2.3 From 40ad5397872bb753063e0edeefc1ad0fdc702f5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 9 Oct 2013 15:10:39 +0200 Subject: qmake: Allow QMAKE_MAC_XCODE_SETTINGS to be limited to debug or release MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Xcode generator does not support exclusive builds, but still generates projects that contain both debug and release configurations, each with hard-coded differences such as whether or not to strip or to generate debug symbols. As a stop-gap solution we allow projects and mkspecs to add extra settings that are limited to a given build. Long term we want to rewrite the Xcode generator to support exclusive builds, but that is a much bigger task. Change-Id: I85056164bb1b3c8c6e0cf66410348cca7138eca5 Reviewed-by: Tor Arne Vestbø --- qmake/generators/mac/pbuilder_pbx.cpp | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp index 719507c61d..ac9e4cc71a 100644 --- a/qmake/generators/mac/pbuilder_pbx.cpp +++ b/qmake/generators/mac/pbuilder_pbx.cpp @@ -301,6 +301,8 @@ ProjectBuilderMakefileGenerator::writeSubDirs(QTextStream &t) QString defaultConfig; for(int as_release = 0; as_release < 2; as_release++) { + QString configName = (as_release ? "Release" : "Debug"); + QMap settings; settings.insert("COPY_PHASE_STRIP", (as_release ? "YES" : "NO")); if(as_release) @@ -311,6 +313,12 @@ ProjectBuilderMakefileGenerator::writeSubDirs(QTextStream &t) const ProStringList &l = project->values("QMAKE_MAC_XCODE_SETTINGS"); for(int i = 0; i < l.size(); ++i) { ProString name = l.at(i); + const ProKey buildKey(name + ".build"); + if (!project->isEmpty(buildKey)) { + const QString build = project->values(buildKey).first().toQString(); + if (build.toLower() != configName.toLower()) + continue; + } const ProKey nkey(name + ".name"); if (!project->isEmpty(nkey)) name = project->first(nkey); @@ -319,10 +327,9 @@ ProjectBuilderMakefileGenerator::writeSubDirs(QTextStream &t) } } - QString name = (as_release ? "Release" : "Debug"); if (project->isActiveConfig("debug") != (bool)as_release) - defaultConfig = name; - QString key = keyFor("QMAKE_SUBDIR_PBX_BUILDCONFIG_" + name); + defaultConfig = configName; + QString key = keyFor("QMAKE_SUBDIR_PBX_BUILDCONFIG_" + configName); project->values("QMAKE_SUBDIR_PBX_BUILDCONFIGS").append(key); t << "\t\t" << key << " = {\n" << "\t\t\t" << writeSettings("isa", "XCBuildConfiguration", SettingsNoQuote) << ";\n" @@ -330,7 +337,7 @@ ProjectBuilderMakefileGenerator::writeSubDirs(QTextStream &t) for (QMap::Iterator set_it = settings.begin(); set_it != settings.end(); ++set_it) t << "\t\t\t\t" << writeSettings(set_it.key(), set_it.value()) << ";\n"; t << "\t\t\t};\n" - << "\t\t\t" << writeSettings("name", name) << ";\n" + << "\t\t\t" << writeSettings("name", configName) << ";\n" << "\t\t};\n"; } t << "\t\t" << keyFor("QMAKE_SUBDIR_PBX_BUILDCONFIG_LIST") << " = {\n" @@ -1244,6 +1251,8 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) QString defaultConfig; for(int as_release = 0; as_release < 2; as_release++) { + QString configName = (as_release ? "Release" : "Debug"); + QMap settings; settings.insert("COPY_PHASE_STRIP", (as_release ? "YES" : "NO")); settings.insert("GCC_GENERATE_DEBUGGING_SYMBOLS", as_release ? "NO" : "YES"); @@ -1255,6 +1264,12 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) const ProStringList &l = project->values("QMAKE_MAC_XCODE_SETTINGS"); for(int i = 0; i < l.size(); ++i) { ProString name = l.at(i); + const ProKey buildKey(name + ".build"); + if (!project->isEmpty(buildKey)) { + const QString build = project->values(buildKey).first().toQString(); + if (build.toLower() != configName.toLower()) + continue; + } const QString value = project->values(ProKey(name + ".value")).join(QString(Option::field_sep)); const ProKey nkey(name + ".name"); if (!project->isEmpty(nkey)) @@ -1271,11 +1286,10 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) settings.insert("PRODUCT_NAME", escapeFilePath(lib.toQString())); } - QString name = (as_release ? "Release" : "Debug"); if (project->isActiveConfig("debug") != (bool)as_release) - defaultConfig = name; + defaultConfig = configName; for (int i = 0; i < buildConfigGroups.size(); i++) { - QString key = keyFor("QMAKE_PBX_BUILDCONFIG_" + name + buildConfigGroups.at(i)); + QString key = keyFor("QMAKE_PBX_BUILDCONFIG_" + configName + buildConfigGroups.at(i)); project->values(ProKey("QMAKE_PBX_BUILDCONFIGS_" + buildConfigGroups.at(i))).append(key); t << "\t\t" << key << " = {\n" << "\t\t\t" << writeSettings("isa", "XCBuildConfiguration", SettingsNoQuote) << ";\n" @@ -1429,7 +1443,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) } } t << "\t\t\t};\n" - << "\t\t\t" << writeSettings("name", name) << ";\n" + << "\t\t\t" << writeSettings("name", configName) << ";\n" << "\t\t};\n"; } } -- cgit v1.2.3 From dd5e40d9c683dbedcde911e1abd7bfcec87ca514 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 11 Oct 2013 12:24:30 +0200 Subject: Allow custom definition of Q_FORWARD_DECLARE_OBJC_CLASS and friends MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I761ef508672d5d4e8b9067a1b5f91debe09607d4 Reviewed-by: Tor Arne Vestbø --- src/corelib/global/qglobal.h | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index b1a22ddf03..d7253c39c6 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -998,13 +998,19 @@ template struct QEnableIf; template struct QEnableIf { typedef T Type; }; } -#ifdef __OBJC__ -#define Q_FORWARD_DECLARE_OBJC_CLASS(classname) @class classname -#else -#define Q_FORWARD_DECLARE_OBJC_CLASS(classname) typedef struct objc_object classname +#ifndef Q_FORWARD_DECLARE_OBJC_CLASS +# ifdef __OBJC__ +# define Q_FORWARD_DECLARE_OBJC_CLASS(classname) @class classname +# else +# define Q_FORWARD_DECLARE_OBJC_CLASS(classname) typedef struct objc_object classname +# endif +#endif +#ifndef Q_FORWARD_DECLARE_CF_TYPE +# define Q_FORWARD_DECLARE_CF_TYPE(type) typedef const struct __ ## type * type ## Ref +#endif +#ifndef Q_FORWARD_DECLARE_MUTABLE_CF_TYPE +# define Q_FORWARD_DECLARE_MUTABLE_CF_TYPE(type) typedef struct __ ## type * type ## Ref #endif -#define Q_FORWARD_DECLARE_CF_TYPE(type) typedef const struct __ ## type * type ## Ref -#define Q_FORWARD_DECLARE_MUTABLE_CF_TYPE(type) typedef struct __ ## type * type ## Ref QT_END_NAMESPACE // Q_GLOBAL_STATIC -- cgit v1.2.3 From f9889534d16290262eced02bc9c9ed1a9afb8fac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 11 Oct 2013 12:43:57 +0200 Subject: Remove last traces of CoreServices/QT_NO_CORESERVICES on Mac MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ia603e717f3b37dc982468eb2b7eb781d7529ccb0 Reviewed-by: Tor Arne Vestbø --- config.tests/mac/coreservices/coreservices.mm | 48 -------------------------- config.tests/mac/coreservices/coreservices.pro | 3 -- configure | 8 ----- mkspecs/macx-ios-clang/qmake.conf | 2 +- 4 files changed, 1 insertion(+), 60 deletions(-) delete mode 100644 config.tests/mac/coreservices/coreservices.mm delete mode 100644 config.tests/mac/coreservices/coreservices.pro diff --git a/config.tests/mac/coreservices/coreservices.mm b/config.tests/mac/coreservices/coreservices.mm deleted file mode 100644 index c5806dcaea..0000000000 --- a/config.tests/mac/coreservices/coreservices.mm +++ /dev/null @@ -1,48 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the config.tests of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/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 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -int main() -{ - FSRef ref; - return 0; -} diff --git a/config.tests/mac/coreservices/coreservices.pro b/config.tests/mac/coreservices/coreservices.pro deleted file mode 100644 index 64936eb974..0000000000 --- a/config.tests/mac/coreservices/coreservices.pro +++ /dev/null @@ -1,3 +0,0 @@ -OBJECTIVE_SOURCES = coreservices.mm -LIBS += -framework CoreServices -CONFIG -= qt diff --git a/configure b/configure index dd2c01c3a4..64568dd476 100755 --- a/configure +++ b/configure @@ -5582,14 +5582,6 @@ if [ "$CFG_KMS" = "yes" ]; then QT_CONFIG="$QT_CONFIG kms" fi -if [ "$BUILD_ON_MAC" = "yes" ]; then - if compileTest mac/coreservices "CoreServices"; then - QT_CONFIG="$QT_CONFIG coreservices" - else - QMakeVar add DEFINES QT_NO_CORESERVICES - fi -fi - if [ "$BUILD_ON_MAC" = "no" ] && [ "$XPLATFORM_MINGW" = "no" ] && [ "$XPLATFORM_QNX" = "no" ] && [ "$XPLATFORM_ANDROID" = "no" ]; then if [ "$CFG_XCB" = "no" ] && [ "$CFG_EGLFS" = "no" ] && [ "$CFG_DIRECTFB" = "no" ] && [ "$CFG_LINUXFB" = "no" ] && [ "$CFG_KMS" = "no" ]; then if [ "$QPA_PLATFORM_GUARD" = "yes" ] && diff --git a/mkspecs/macx-ios-clang/qmake.conf b/mkspecs/macx-ios-clang/qmake.conf index 38de1e9b0a..b8ef04858a 100644 --- a/mkspecs/macx-ios-clang/qmake.conf +++ b/mkspecs/macx-ios-clang/qmake.conf @@ -10,7 +10,7 @@ QMAKE_MACOSX_DEPLOYMENT_TARGET = QMAKE_IOS_DEPLOYMENT_TARGET = 5.0 INCLUDEPATH += $$PWD/ios -DEFINES += DARWIN_NO_CARBON QT_NO_CORESERVICES QT_NO_PRINTER QT_NO_PRINTDIALOG +DEFINES += DARWIN_NO_CARBON QT_NO_PRINTER QT_NO_PRINTDIALOG # Universal target (iPhone and iPad) QMAKE_IOS_TARGETED_DEVICE_FAMILY = 1,2 -- cgit v1.2.3 From 7a47aebe9ed41d6cd9c9bcd45758d4d553668e99 Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 10 Oct 2013 17:06:37 +0200 Subject: Let QLoggingCategory::defaultCategory return a pointer The pointer can be null. Going trough the reference invokes undefined behavior here. Change-Id: Ia84e4e732cdcbbaee0f5f0679765d18069ea8b2d Reviewed-by: Kai Koehne --- src/corelib/global/qlogging.cpp | 2 +- src/corelib/io/qloggingcategory.cpp | 15 +++++++--- src/corelib/io/qloggingcategory.h | 2 +- .../io/qloggingcategory/tst_qloggingcategory.cpp | 32 +++++++++++----------- 4 files changed, 29 insertions(+), 22 deletions(-) diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp index 063e94069f..b9b5173881 100644 --- a/src/corelib/global/qlogging.cpp +++ b/src/corelib/global/qlogging.cpp @@ -927,7 +927,7 @@ static void qt_message_print(QtMsgType msgType, const QMessageLogContext &contex #ifndef QT_BOOTSTRAPPED // qDebug, qWarning, ... macros do not check whether category is enabled if (!context.category || (strcmp(context.category, "default") == 0)) { - if (QLoggingCategory *defaultCategory = &QLoggingCategory::defaultCategory()) { + if (QLoggingCategory *defaultCategory = QLoggingCategory::defaultCategory()) { if (!defaultCategory->isEnabled(msgType)) return; } diff --git a/src/corelib/io/qloggingcategory.cpp b/src/corelib/io/qloggingcategory.cpp index 6c5df1e8e7..2ef392c209 100644 --- a/src/corelib/io/qloggingcategory.cpp +++ b/src/corelib/io/qloggingcategory.cpp @@ -244,12 +244,19 @@ void QLoggingCategory::setEnabled(QtMsgType type, bool enable) */ /*! - Returns the category \c "default" that is used e.g. by qDebug(), qWarning(), - qCritical(), qFatal(). + Returns a pointer to the global category \c "default" that + is used e.g. by qDebug(), qWarning(), qCritical(), qFatal(). + + \note The returned pointer may be null during destruction of + static objects. + + \note Ownership of the category is not transferred, do not + \c delete the returned pointer. + */ -QLoggingCategory &QLoggingCategory::defaultCategory() +QLoggingCategory *QLoggingCategory::defaultCategory() { - return *qtDefaultCategory(); + return qtDefaultCategory(); } /*! diff --git a/src/corelib/io/qloggingcategory.h b/src/corelib/io/qloggingcategory.h index 35da04c8f2..6009226127 100644 --- a/src/corelib/io/qloggingcategory.h +++ b/src/corelib/io/qloggingcategory.h @@ -72,7 +72,7 @@ public: // allows usage of both factory method and variable in qCX macros QLoggingCategory &operator()() { return *this; } - static QLoggingCategory &defaultCategory(); + static QLoggingCategory *defaultCategory(); typedef void (*CategoryFilter)(QLoggingCategory*); static CategoryFilter installFilter(CategoryFilter); diff --git a/tests/auto/corelib/io/qloggingcategory/tst_qloggingcategory.cpp b/tests/auto/corelib/io/qloggingcategory/tst_qloggingcategory.cpp index df93262d93..a49793c3d4 100644 --- a/tests/auto/corelib/io/qloggingcategory/tst_qloggingcategory.cpp +++ b/tests/auto/corelib/io/qloggingcategory/tst_qloggingcategory.cpp @@ -226,7 +226,7 @@ private slots: void QLoggingCategory_categoryName() { logMessage.clear(); - QCOMPARE(QString::fromLatin1(QLoggingCategory::defaultCategory().categoryName()), + QCOMPARE(QString::fromLatin1(QLoggingCategory::defaultCategory()->categoryName()), QStringLiteral("default")); QLoggingCategory defaultCategory("default"); @@ -237,7 +237,7 @@ private slots: QCOMPARE(QByteArray(nullCategory.categoryName()), QByteArray("default")); // we rely on the same pointer for any "default" category - QCOMPARE(QLoggingCategory::defaultCategory().categoryName(), + QCOMPARE(QLoggingCategory::defaultCategory()->categoryName(), defaultCategory.categoryName()); QCOMPARE(defaultCategory.categoryName(), nullCategory.categoryName()); @@ -256,12 +256,12 @@ private slots: { logMessage.clear(); - QCOMPARE(QLoggingCategory::defaultCategory().isDebugEnabled(), true); - QCOMPARE(QLoggingCategory::defaultCategory().isEnabled(QtDebugMsg), true); - QCOMPARE(QLoggingCategory::defaultCategory().isWarningEnabled(), true); - QCOMPARE(QLoggingCategory::defaultCategory().isEnabled(QtWarningMsg), true); - QCOMPARE(QLoggingCategory::defaultCategory().isCriticalEnabled(), true); - QCOMPARE(QLoggingCategory::defaultCategory().isEnabled(QtCriticalMsg), true); + QCOMPARE(QLoggingCategory::defaultCategory()->isDebugEnabled(), true); + QCOMPARE(QLoggingCategory::defaultCategory()->isEnabled(QtDebugMsg), true); + QCOMPARE(QLoggingCategory::defaultCategory()->isWarningEnabled(), true); + QCOMPARE(QLoggingCategory::defaultCategory()->isEnabled(QtWarningMsg), true); + QCOMPARE(QLoggingCategory::defaultCategory()->isCriticalEnabled(), true); + QCOMPARE(QLoggingCategory::defaultCategory()->isEnabled(QtCriticalMsg), true); QLoggingCategory defaultCategory("default"); QCOMPARE(defaultCategory.isDebugEnabled(), true); @@ -287,11 +287,11 @@ private slots: { logMessage.clear(); - QCOMPARE(QLoggingCategory::defaultCategory().isDebugEnabled(), true); + QCOMPARE(QLoggingCategory::defaultCategory()->isDebugEnabled(), true); - QLoggingCategory::defaultCategory().setEnabled(QtDebugMsg, false); - QCOMPARE(QLoggingCategory::defaultCategory().isDebugEnabled(), false); - QLoggingCategory::defaultCategory().setEnabled(QtDebugMsg, true); + QLoggingCategory::defaultCategory()->setEnabled(QtDebugMsg, false); + QCOMPARE(QLoggingCategory::defaultCategory()->isDebugEnabled(), false); + QLoggingCategory::defaultCategory()->setEnabled(QtDebugMsg, true); // make sure nothing has printed warnings QVERIFY(logMessage.isEmpty()); @@ -300,13 +300,13 @@ private slots: void QLoggingCategory_installFilter() { - QVERIFY(QLoggingCategory::defaultCategory().isDebugEnabled()); + QVERIFY(QLoggingCategory::defaultCategory()->isDebugEnabled()); QLoggingCategory::CategoryFilter defaultFilter = QLoggingCategory::installFilter(customCategoryFilter); QVERIFY(defaultFilter); customCategoryFilterArgs.clear(); - QVERIFY(!QLoggingCategory::defaultCategory().isDebugEnabled()); + QVERIFY(!QLoggingCategory::defaultCategory()->isDebugEnabled()); QLoggingCategory cat("custom"); QCOMPARE(customCategoryFilterArgs, QStringList() << "custom"); @@ -319,7 +319,7 @@ private slots: QCOMPARE((void*)currentFilter, (void*)customCategoryFilter); QCOMPARE(customCategoryFilterArgs.size(), 0); - QVERIFY(QLoggingCategory::defaultCategory().isDebugEnabled()); + QVERIFY(QLoggingCategory::defaultCategory()->isDebugEnabled()); QVERIFY(!cat.isDebugEnabled()); // install default filter @@ -328,7 +328,7 @@ private slots: QCOMPARE((void*)defaultFilter, (void*)currentFilter); QCOMPARE(customCategoryFilterArgs.size(), 0); - QVERIFY(QLoggingCategory::defaultCategory().isDebugEnabled()); + QVERIFY(QLoggingCategory::defaultCategory()->isDebugEnabled()); QVERIFY(!cat.isDebugEnabled()); } -- cgit v1.2.3 From e1e2b2d8ca89bbd90afe3e884e95bc7372bd22d5 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 2 Sep 2013 09:50:19 +0200 Subject: qml_plugin.prf: moc plugin with -Muri=$$TARGETPATH When we build qml plugins, we now depend on embedding the uri of the plugin into its meta-data using the new -M switch to moc for static builds. This patch will let this happen automatically whenever you call load(qml_plugin) from your pro file. With this patch, you only need to rebuild your plugin to support static applications. Task-number: QTBUG-28357 Change-Id: I99e2fc80688fa43cf734551553f4fa0cb5ed47ed Reviewed-by: Simon Hausmann --- mkspecs/features/qml_plugin.prf | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mkspecs/features/qml_plugin.prf b/mkspecs/features/qml_plugin.prf index 28fbb392a7..af941058db 100644 --- a/mkspecs/features/qml_plugin.prf +++ b/mkspecs/features/qml_plugin.prf @@ -25,6 +25,11 @@ if(win32|mac):!macx-xcode { } isEmpty(TARGETPATH): TARGETPATH = $$eval(QT.$${CXX_MODULE}.name) +# Insert the plugins URI into its meta data to enable usage +# of static plugins in QtDeclarative: +URI = $$replace(TARGETPATH, "/", ".") +QMAKE_MOC_OPTIONS += -Muri=$$URI + QMLTYPEFILE = $$_PRO_FILE_PWD_/plugins.qmltypes exists($$QMLTYPEFILE): QML_FILES += $$QMLTYPEFILE -- cgit v1.2.3 From a9bad65b091d15b0446fa141e0a69ebb94b38b70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 11 Oct 2013 15:48:44 +0200 Subject: qmake: Update internal mkspec on changes to QMAKESPEC Allows the macx-xcode mkspec to be a wrapper around other mkspecs. Since QMAKESPEC can now be set in the spec, we have to ensure not to append to QMAKESPEC. Change-Id: Idf33ff38147f14c488f14b426c02d9a739fdaecf Reviewed-by: Oswald Buddenhagen --- qmake/library/qmakeevaluator.cpp | 9 ++++++++- qmake/library/qmakeevaluator_p.h | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/qmake/library/qmakeevaluator.cpp b/qmake/library/qmakeevaluator.cpp index 9a2bcd7680..c4dca12900 100644 --- a/qmake/library/qmakeevaluator.cpp +++ b/qmake/library/qmakeevaluator.cpp @@ -129,6 +129,7 @@ void QMakeEvaluator::initStatics() statics.strhost_build = QLatin1String("host_build"); statics.strTEMPLATE = ProKey("TEMPLATE"); statics.strQMAKE_PLATFORM = ProKey("QMAKE_PLATFORM"); + statics.strQMAKESPEC = ProKey("QMAKESPEC"); #ifdef PROEVALUATOR_FULL statics.strREQUIRES = ProKey("REQUIRES"); #endif @@ -939,6 +940,12 @@ void QMakeEvaluator::visitProVariable( setTemplate(); else if (varName == statics.strQMAKE_PLATFORM) m_featureRoots = 0; + else if (varName == statics.strQMAKESPEC) { + if (!values(varName).isEmpty()) { + m_qmakespec = values(varName).first().toQString(); + m_featureRoots = 0; + } + } #ifdef PROEVALUATOR_FULL else if (varName == statics.strREQUIRES) checkRequirements(values(varName)); @@ -1160,7 +1167,7 @@ bool QMakeEvaluator::loadSpecInternal() m_qmakespec = orig_spec.toQString(); # endif #endif - valuesRef(ProKey("QMAKESPEC")) << ProString(m_qmakespec); + valuesRef(ProKey("QMAKESPEC")) = ProString(m_qmakespec); m_qmakespecName = IoUtils::fileName(m_qmakespec).toString(); // This also ensures that m_featureRoots is valid. if (evaluateFeatureFile(QLatin1String("spec_post.prf")) != ReturnTrue) diff --git a/qmake/library/qmakeevaluator_p.h b/qmake/library/qmakeevaluator_p.h index c6cb60744f..dd0bdd4c7f 100644 --- a/qmake/library/qmakeevaluator_p.h +++ b/qmake/library/qmakeevaluator_p.h @@ -91,6 +91,7 @@ struct QMakeStatics { QString strhost_build; ProKey strTEMPLATE; ProKey strQMAKE_PLATFORM; + ProKey strQMAKESPEC; #ifdef PROEVALUATOR_FULL ProKey strREQUIRES; #endif -- cgit v1.2.3 From 4723f3fd04edf1aad6750ca91fd4648216d8b408 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fatih=20A=C5=9F=C4=B1c=C4=B1?= Date: Sat, 21 Sep 2013 00:14:39 +0300 Subject: configure: Parse -device-option value correctly The regular expression does not parse correctly when a device option value contains the character '=' (e.g. QMAKE_CFLAGS="-D_FILE_OFFSET_BITS=64"). In order to break string at the first equal sign and to simplify code, use "cut" command as in other places in configure script. Task-number: QTBUG-33584 Change-Id: I05b474d2ba6bff84c1e40d00475963bab36d94b6 Reviewed-by: Oswald Buddenhagen --- configure | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure b/configure index 64568dd476..388899e5e4 100755 --- a/configure +++ b/configure @@ -1609,8 +1609,8 @@ while [ "$#" -gt 0 ]; do [ "$XPLATFORM" = "undefined" ] && exit 101 ;; device-option) - DEV_VAR=`echo $VAL | sed "s,^\(.*\)=.*,\1,"` - DEV_VAL=`echo $VAL | sed "s,^.*=\(.*\),\1,"` + DEV_VAR=`echo $VAL | cut -d '=' -f 1` + DEV_VAL=`echo $VAL | cut -d '=' -f 2-` DeviceVar set $DEV_VAR "$DEV_VAL" ;; qpa) -- cgit v1.2.3 From 58de01b54bf34c5ee416c1d6fe5e5d1c5bc89e5f Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 7 Oct 2013 18:53:49 +0200 Subject: fix setting of output directory of SUBDIRS with -tp vs amends ec145129c. Investigated-by: Nikolai Tasev Task-number: QTBUG-32375 Change-Id: Iff27c03c0bb4f739dad9d10bae9576946948041b Reviewed-by: Andy Shaw Reviewed-by: Joerg Bornemann --- qmake/generators/win32/msvc_vcproj.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index 86d31b01dc..a30129fa27 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -449,7 +449,7 @@ ProStringList VcprojGenerator::collectDependencies(QMakeProject *proj, QHashshadowedPath(QDir::cleanPath(fi.absoluteFilePath())); + Option::output_dir = Option::globals->shadowedPath(QDir::cleanPath(dir)); if (tmp_proj.read(fn)) { // Check if all requirements are fulfilled if (!tmp_proj.isEmpty("QMAKE_FAILED_REQUIREMENTS")) { -- cgit v1.2.3 From bc92ca1860c575863466e5eeef6b253690515824 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 7 Oct 2013 20:19:19 +0200 Subject: include privates the right way Task-number: QTBUG-33496 Change-Id: Id23e00627cb7896ba44c8b612ce4aff980750f7d Reviewed-by: aavit --- src/gui/kernel/qplatformtheme.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/kernel/qplatformtheme.cpp b/src/gui/kernel/qplatformtheme.cpp index 3fb4939b69..562df1c913 100644 --- a/src/gui/kernel/qplatformtheme.cpp +++ b/src/gui/kernel/qplatformtheme.cpp @@ -48,8 +48,8 @@ #include #include #include -#include -#include "private/qguiapplication_p.h" +#include +#include QT_BEGIN_NAMESPACE -- cgit v1.2.3 From 9c5e63ceb3048503d1b0b87916aae011b9b79ccf Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 8 Oct 2013 14:49:37 +0200 Subject: support building with -no-gui Change-Id: I1c418e2aa6c01dbc40156a3494a7f7ddc95beca3 Reviewed-by: Sergio Ahumada Reviewed-by: Jason McDonald --- tests/auto/testlib/selftests/cmptest/cmptest.pro | 3 ++- tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/auto/testlib/selftests/cmptest/cmptest.pro b/tests/auto/testlib/selftests/cmptest/cmptest.pro index a793c203dd..2d5dd071a9 100644 --- a/tests/auto/testlib/selftests/cmptest/cmptest.pro +++ b/tests/auto/testlib/selftests/cmptest/cmptest.pro @@ -1,5 +1,6 @@ SOURCES += tst_cmptest.cpp -QT = core gui testlib +QT = core testlib +qtHaveModule(gui): QT += gui mac:CONFIG -= app_bundle CONFIG -= debug_and_release_target diff --git a/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp b/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp index e9ad1778fa..9f8343b57a 100644 --- a/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp +++ b/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp @@ -42,8 +42,10 @@ #include #include +#ifdef QT_GUI_LIB #include #include +#endif /* XPM test data for QPixmap, QImage tests (use drag cursors as example) */ @@ -138,10 +140,12 @@ private slots: void compareQStringLists_data(); void compareQListInt(); void compareQListDouble(); +#ifdef QT_GUI_LIB void compareQPixmaps(); void compareQPixmaps_data(); void compareQImages(); void compareQImages_data(); +#endif }; static bool boolfunc() { return true; } @@ -323,6 +327,7 @@ void tst_Cmptest::compareQListDouble() QCOMPARE(double1, double2); } +#ifdef QT_GUI_LIB void tst_Cmptest::compareQPixmaps_data() { QTest::addColumn("opA"); @@ -374,6 +379,7 @@ void tst_Cmptest::compareQImages() QCOMPARE(opA, opB); } +#endif QTEST_MAIN(tst_Cmptest) #include "tst_cmptest.moc" -- cgit v1.2.3 From 90c65880b0ddf07768931df66a0c421af4c287cd Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 8 Oct 2013 12:14:46 +0200 Subject: skip gui-needing examples with -no-gui Change-Id: I2413f14f0c2d9179868877615d6131bf4ca7ea16 Reviewed-by: Sergio Ahumada --- examples/gui/gui.pro | 2 ++ examples/qpa/qpa.pro | 2 ++ examples/qtconcurrent/qtconcurrent.pro | 5 +++++ 3 files changed, 9 insertions(+) diff --git a/examples/gui/gui.pro b/examples/gui/gui.pro index 8758a1ba95..5fb4241e74 100644 --- a/examples/gui/gui.pro +++ b/examples/gui/gui.pro @@ -1,3 +1,5 @@ +requires(qtHaveModule(gui)) + TEMPLATE = subdirs CONFIG += no_docs_target diff --git a/examples/qpa/qpa.pro b/examples/qpa/qpa.pro index 6f07e50fd8..27293482ef 100644 --- a/examples/qpa/qpa.pro +++ b/examples/qpa/qpa.pro @@ -1,2 +1,4 @@ +requires(qtHaveModule(gui)) + TEMPLATE = subdirs SUBDIRS = windows diff --git a/examples/qtconcurrent/qtconcurrent.pro b/examples/qtconcurrent/qtconcurrent.pro index 1df6f2d8cf..6e4e5f0f16 100644 --- a/examples/qtconcurrent/qtconcurrent.pro +++ b/examples/qtconcurrent/qtconcurrent.pro @@ -10,6 +10,11 @@ SUBDIRS = imagescaling \ SUBDIRS += progressdialog } +!qtHaveModule(gui) { + SUBDIRS -= \ + map +} + !qtHaveModule(widgets) { SUBDIRS -= \ imagescaling \ -- cgit v1.2.3 From 580096d61190f6ec0405ed1babe3e7593b705239 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 8 Oct 2013 14:48:25 +0200 Subject: rewrite qtMetaObjectInheritance() without gui Change-Id: Ie024a3ee755cfe4996ed442686cd73ce13a2d5ff Reviewed-by: Olivier Goffart --- tests/auto/corelib/kernel/qmetaobject/qmetaobject.pro | 2 +- .../auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/auto/corelib/kernel/qmetaobject/qmetaobject.pro b/tests/auto/corelib/kernel/qmetaobject/qmetaobject.pro index 0800b71c22..509ade6e2a 100644 --- a/tests/auto/corelib/kernel/qmetaobject/qmetaobject.pro +++ b/tests/auto/corelib/kernel/qmetaobject/qmetaobject.pro @@ -1,6 +1,6 @@ CONFIG += testcase CONFIG += parallel_test TARGET = tst_qmetaobject -QT = core-private gui testlib +QT = core-private testlib SOURCES = tst_qmetaobject.cpp DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp b/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp index 4f1320e375..870e65f0cc 100644 --- a/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp +++ b/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp @@ -43,7 +43,7 @@ #include #include -#include +#include #include Q_DECLARE_METATYPE(const QMetaObject *) @@ -746,13 +746,13 @@ void tst_QMetaObject::invokeBlockingQueuedMetaMember() void tst_QMetaObject::qtMetaObjectInheritance() { QVERIFY(QObject::staticMetaObject.superClass() == 0); - QCOMPARE(QWindow::staticMetaObject.indexOfEnumerator("Qt::ScreenOrientation"), -1); - QCOMPARE(QWindow::staticMetaObject.indexOfEnumerator("ScreenOrientation"), -1); - int indexOfContentOrientation = QWindow::staticMetaObject.indexOfProperty("contentOrientation"); - QVERIFY(indexOfContentOrientation != -1); - QMetaProperty contentOrientation = QWindow::staticMetaObject.property(indexOfContentOrientation); - QVERIFY(contentOrientation.isValid()); - QCOMPARE(contentOrientation.enumerator().name(), "ScreenOrientation"); + QCOMPARE(QSortFilterProxyModel::staticMetaObject.indexOfEnumerator("Qt::CaseSensitivity"), -1); + QCOMPARE(QSortFilterProxyModel::staticMetaObject.indexOfEnumerator("CaseSensitivity"), -1); + int indexOfSortCaseSensitivity = QSortFilterProxyModel::staticMetaObject.indexOfProperty("sortCaseSensitivity"); + QVERIFY(indexOfSortCaseSensitivity != -1); + QMetaProperty sortCaseSensitivity = QSortFilterProxyModel::staticMetaObject.property(indexOfSortCaseSensitivity); + QVERIFY(sortCaseSensitivity.isValid()); + QCOMPARE(sortCaseSensitivity.enumerator().name(), "CaseSensitivity"); } struct MyType -- cgit v1.2.3 From 40d4c1b2ed24016d1860e21c7fd9d374c387f82d Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 11 Oct 2013 16:25:01 +0200 Subject: make sure that installed meta files are always postprocessed the problem is that there is no sed command on windows ... so build it into qmake and invoke that from the generated makefiles. cmake does the same, after all. ^^ Task-number: QTBUG-33794 Change-Id: Ib7077e18acbc5edd79f714c5779a5ed31ea6c093 Reviewed-by: Joerg Bornemann --- mkspecs/common/shell-win32.conf | 1 + qmake/generators/makefile.cpp | 3 +- qmake/generators/win32/winmakefile.cpp | 2 + qmake/main.cpp | 128 +++++++++++++++++++++++++++++++++ 4 files changed, 132 insertions(+), 2 deletions(-) diff --git a/mkspecs/common/shell-win32.conf b/mkspecs/common/shell-win32.conf index 131aa746c4..1da8057c43 100644 --- a/mkspecs/common/shell-win32.conf +++ b/mkspecs/common/shell-win32.conf @@ -14,3 +14,4 @@ QMAKE_SYMBOLIC_LINK = $$QMAKE_COPY QMAKE_LN_SHLIB = $$QMAKE_SYMBOLIC_LINK # xcopy copies the contained files if source is a directory. Deal with it. CONFIG += copy_dir_files +QMAKE_STREAM_EDITOR = $(QMAKE) -install sed diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index 570f3216e3..3bc5f00cab 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -3331,8 +3331,7 @@ QString MakefileGenerator::installMetaFile(const ProKey &replace_rule, const QSt { QString ret; if (project->isEmpty(replace_rule) - || project->isActiveConfig("no_sed_meta_install") - || project->isEmpty("QMAKE_STREAM_EDITOR")) { + || project->isActiveConfig("no_sed_meta_install")) { ret += "-$(INSTALL_FILE) \"" + src + "\" \"" + dst + "\""; } else { ret += "-$(SED)"; diff --git a/qmake/generators/win32/winmakefile.cpp b/qmake/generators/win32/winmakefile.cpp index 0ad0f09bce..30d28e6e11 100644 --- a/qmake/generators/win32/winmakefile.cpp +++ b/qmake/generators/win32/winmakefile.cpp @@ -301,6 +301,8 @@ void Win32MakefileGenerator::processVars() project->values("QMAKE_COPY_FILE").append("$(COPY)"); if(project->isEmpty("QMAKE_COPY_DIR")) project->values("QMAKE_COPY_DIR").append("xcopy /s /q /y /i"); + if (project->isEmpty("QMAKE_STREAM_EDITOR")) + project->values("QMAKE_STREAM_EDITOR").append("$(QMAKE) -install sed"); if(project->isEmpty("QMAKE_INSTALL_FILE")) project->values("QMAKE_INSTALL_FILE").append("$(COPY_FILE)"); if(project->isEmpty("QMAKE_INSTALL_PROGRAM")) diff --git a/qmake/main.cpp b/qmake/main.cpp index 66364b83a7..b1929e0d21 100644 --- a/qmake/main.cpp +++ b/qmake/main.cpp @@ -57,6 +57,128 @@ QT_BEGIN_NAMESPACE +#ifdef Q_OS_WIN + +struct SedSubst { + QRegExp from; + QString to; +}; +Q_DECLARE_TYPEINFO(SedSubst, Q_MOVABLE_TYPE); + +static int doSed(int argc, char **argv) +{ + QVector substs; + QList inFiles; + for (int i = 0; i < argc; i++) { + if (!strcmp(argv[i], "-e")) { + if (++i == argc) { + fprintf(stderr, "Error: sed option -e requires an argument\n"); + return 3; + } + QString cmd = QString::fromLocal8Bit(argv[i]); + for (int j = 0; j < cmd.length(); j++) { + QChar c = cmd.at(j); + if (c.isSpace()) + continue; + if (c != QLatin1Char('s')) { + fprintf(stderr, "Error: unrecognized sed command '%c'\n", c.toLatin1()); + return 3; + } + QChar sep = ++j < cmd.length() ? cmd.at(j) : QChar(); + bool escaped = false; + int phase = 1; + QStringList phases; + QString curr; + while (++j < cmd.length()) { + c = cmd.at(j); + if (!escaped) { + if (c == QLatin1Char(';')) + break; + if (c == QLatin1Char('\\')) { + escaped = true; + continue; + } + if (c == sep) { + phase++; + phases << curr; + curr.clear(); + continue; + } + } + if (phase == 1 + && (c == QLatin1Char('+') || c == QLatin1Char('?') + || c == QLatin1Char('{') || c == QLatin1Char('}') + || c == QLatin1Char('(') || c == QLatin1Char(')'))) { + // translate sed rx to QRegExp + escaped ^= 1; + } + if (escaped) { + escaped = false; + curr += QLatin1Char('\\'); + } + curr += c; + } + if (escaped) { + fprintf(stderr, "Error: unterminated escape sequence in sed s command\n"); + return 3; + } + if (phase != 3) { + fprintf(stderr, "Error: sed s command requires three arguments (%d, %c, %s)\n", phase, sep.toLatin1(), qPrintable(curr)); + return 3; + } + if (curr != QLatin1String("g")) { + fprintf(stderr, "Error: sed s command must be used with the g option (only)\n"); + return 3; + } + SedSubst subst; + subst.from = QRegExp(phases.at(0)); + subst.to = phases.at(1); + substs << subst; + } + } else if (argv[i][0] == '-' && argv[i][1] != 0) { + fprintf(stderr, "Error: unrecognized sed option '%s'\n", argv[i]); + return 3; + } else { + inFiles << argv[i]; + } + } + if (inFiles.isEmpty()) + inFiles << "-"; + foreach (const char *inFile, inFiles) { + FILE *f; + if (!strcmp(inFile, "-")) { + f = stdin; + } else if (!(f = fopen(inFile, "r"))) { + perror(inFile); + return 1; + } + QTextStream is(f); + while (!is.atEnd()) { + QString line = is.readLine(); + for (int i = 0; i < substs.size(); i++) + line.replace(substs.at(i).from, substs.at(i).to); + puts(qPrintable(line)); + } + if (f != stdin) + fclose(f); + } + return 0; +} + +static int doInstall(int argc, char **argv) +{ + if (!argc) { + fprintf(stderr, "Error: -install requires further arguments\n"); + return 3; + } + if (!strcmp(argv[0], "sed")) + return doSed(argc - 1, argv + 1); + fprintf(stderr, "Error: unrecognized -install subcommand '%s'\n", argv[0]); + return 3; +} + +#endif // Q_OS_WIN + /* This is to work around lame implementation on Darwin. It has been noted that the getpwd(3) function is much too slow, and called much too often inside of Qt (every fileFixify). With this we use a locally cached copy because I can control all the times it is set (because Qt never sets the pwd under me). @@ -85,6 +207,12 @@ int runQMake(int argc, char **argv) // This is particularly important for things like QtCreator and scripted builds. setvbuf(stdout, (char *)NULL, _IONBF, 0); +#ifdef Q_OS_WIN + // Workaround for inferior/missing command line tools on Windows: make our own! + if (argc >= 2 && !strcmp(argv[1], "-install")) + return doInstall(argc - 2, argv + 2); +#endif + QMakeVfs vfs; Option::vfs = &vfs; QMakeGlobals globals; -- cgit v1.2.3 From 257e98917c2b9c1bc06272eb663a73ee57c094c1 Mon Sep 17 00:00:00 2001 From: Harri Porten Date: Fri, 11 Oct 2013 08:07:27 +0200 Subject: Re-add deprecated symbol for ABI compatibility with Qt 5.1. When b0b786a2f05e9451a65519ab8904f55c35f51b7d deprecated QFontDatabase::supportsThreadedFontRendering() it made the function inline also. That way compilers like gcc did not export the symbol anymore. Change-Id: If9c343eaa2ff90540decbc19b0af33d439c0bbaa Reviewed-by: Konstantin Ritt Reviewed-by: Lars Knoll --- src/gui/text/qfontdatabase.h | 2 +- src/gui/text/qfontdatabase_qpa.cpp | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/gui/text/qfontdatabase.h b/src/gui/text/qfontdatabase.h index 4e8f718962..708b8cbd58 100644 --- a/src/gui/text/qfontdatabase.h +++ b/src/gui/text/qfontdatabase.h @@ -151,7 +151,7 @@ public: static bool removeAllApplicationFonts(); #if QT_DEPRECATED_SINCE(5, 2) - QT_DEPRECATED static inline bool supportsThreadedFontRendering() { return true; } + QT_DEPRECATED static bool supportsThreadedFontRendering(); #endif static QFont systemFont(SystemFont type); diff --git a/src/gui/text/qfontdatabase_qpa.cpp b/src/gui/text/qfontdatabase_qpa.cpp index 7f5281131e..6c0be950dc 100644 --- a/src/gui/text/qfontdatabase_qpa.cpp +++ b/src/gui/text/qfontdatabase_qpa.cpp @@ -267,6 +267,12 @@ bool QFontDatabase::removeAllApplicationFonts() return true; } +// QT_DEPRECATED_SINCE(5, 2) +bool QFontDatabase::supportsThreadedFontRendering() +{ + return true; +} + /*! \internal */ -- cgit v1.2.3 From 3fe242781e88224d121ebca730db5ebe4fb98ec6 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Thu, 10 Oct 2013 22:57:08 +0200 Subject: Export the block's line-height settings to html Task-number: QTBUG-28404 Change-Id: I87e03ecd981c302a5aefdadf7bcfd9729e37bd13 Reviewed-by: Eskil Abrahamsen Blomfeldt Reviewed-by: Simon Hausmann --- src/gui/text/qtextdocument.cpp | 23 ++++++++++++++++++++++ .../gui/text/qtextdocument/tst_qtextdocument.cpp | 20 +++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp index 03602712cc..30e0f32547 100644 --- a/src/gui/text/qtextdocument.cpp +++ b/src/gui/text/qtextdocument.cpp @@ -2531,6 +2531,29 @@ void QTextHtmlExporter::emitBlockAttributes(const QTextBlock &block) html += QLatin1Char(';'); } + if (format.lineHeightType() != QTextBlockFormat::SingleHeight) { + switch (format.lineHeightType()) { + case QTextBlockFormat::ProportionalHeight: + case QTextBlockFormat::FixedHeight: + html += QLatin1String(" line-height:"); + break; + case QTextBlockFormat::MinimumHeight: + html += QLatin1String(" min-height:"); + break; + case QTextBlockFormat::LineDistanceHeight: + html += QLatin1String(" line-spacing:"); + break; + case QTextBlockFormat::SingleHeight: + default: + break; // Should never reach here + } + html += QString::number(format.lineHeight()); + if (format.lineHeightType() == QTextBlockFormat::ProportionalHeight) + html += QLatin1String("%;"); + else + html += QLatin1String("px;"); + } + emitPageBreakPolicy(format.pageBreakPolicy()); QTextCharFormat diff; diff --git a/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp b/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp index 10e79065ee..307e5a6210 100644 --- a/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp +++ b/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp @@ -113,6 +113,7 @@ private slots: void toHtmlBodyBgColorRgba(); void toHtmlBodyBgColorTransparent(); void toHtmlRootFrameProperties(); + void toHtmlLineHeightProperties(); void capitalizationHtmlInExport(); void wordspacingHtmlExport(); @@ -1856,6 +1857,25 @@ void tst_QTextDocument::toHtmlRootFrameProperties() QCOMPARE(doc.toHtml(), expectedOutput); } +void tst_QTextDocument::toHtmlLineHeightProperties() +{ + CREATE_DOC_AND_CURSOR(); + + QTextBlock block = doc.firstBlock(); + QTextBlockFormat blockFormat = block.blockFormat(); + blockFormat.setLineHeight(200, QTextBlockFormat::ProportionalHeight); + cursor.setBlockFormat(blockFormat); + + cursor.insertText("Blah"); + QString expectedOutput("

Blah

"); + + expectedOutput.prepend(htmlHead); + expectedOutput.replace("DEFAULTBLOCKSTYLE", "style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"); + expectedOutput.append(htmlTail); + + QCOMPARE(doc.toHtml(), expectedOutput); +} + void tst_QTextDocument::capitalizationHtmlInExport() { doc->setPlainText("Test"); -- cgit v1.2.3 From dc860e2e0807ebd43938c8efdc3a282d0098e33e Mon Sep 17 00:00:00 2001 From: Marcel Krems Date: Thu, 10 Oct 2013 15:30:05 +0200 Subject: Doc: Fix typos and add missing words. Change-Id: I40e4780bcabbca29425945a69d8a0781cd5c0e9f Reviewed-by: Jerome Pasion --- src/corelib/tools/qalgorithms.qdoc | 2 +- src/corelib/tools/qstring.cpp | 4 ++-- src/gui/text/qtextlayout.cpp | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/corelib/tools/qalgorithms.qdoc b/src/corelib/tools/qalgorithms.qdoc index 4eb7a170dc..cd389470a4 100644 --- a/src/corelib/tools/qalgorithms.qdoc +++ b/src/corelib/tools/qalgorithms.qdoc @@ -764,7 +764,7 @@ \relates \since 5.2 - Returns the number of bits set in \a v. This number also called + Returns the number of bits set in \a v. This number is also called the Hamming Weight of \a v. */ diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 8519eaa17a..0e99a5839c 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -9799,8 +9799,8 @@ QString QString::toHtmlEscaped() const if (attribute.name() == QLatin1String("http-contents-length")) //... \endcode - \note There some restrictions when using the MSVC 2010 or 2012 compilers. The example snippets provided here - fail to compile with them. + \note There are some restrictions when using the MSVC 2010 or 2012 compilers. The example snippets + provided here fail to compile with them. \list \li Concatenated string literals cannot be used with QStringLiteral. \code diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index dc8ae06868..54d337ecc5 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -207,7 +207,7 @@ void QTextInlineObject::setAscent(qreal a) } /*! - Sets the inline object's decent to \a d. + Sets the inline object's descent to \a d. \sa descent(), setAscent(), width(), rect() */ @@ -1288,7 +1288,7 @@ void QTextLayout::drawCursor(QPainter *p, const QPointF &pos, int cursorPosition After being created, the line can be filled using the setLineWidth() or setNumColumns() functions. A line has a number of attributes including the rectangle it occupies, rect(), its coordinates, x() and y(), its - textLength(), width() and naturalTextWidth(), and its ascent() and decent() + textLength(), width() and naturalTextWidth(), and its ascent() and descent() relative to the text. The position of the cursor in terms of the line is available from cursorToX() and its inverse from xToCursor(). A line can be moved with setPosition(). -- cgit v1.2.3 From 95174083ae811e55e4f2b004b6307a5cabe5ec2d Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Thu, 10 Oct 2013 12:37:55 +0200 Subject: Fix compilation with older MinGW headers Headers from mingw.org (4.7.2) declares _flushall only if __STRICT_ANSI__ is not defined ... Anyhow, we can as well use fflush(), which is in the official standard. Change-Id: Ic2b4d2ac724280f1304221be1fceab067af0c1f8 Reviewed-by: Samuel Gaist Reviewed-by: Friedemann Kleint --- src/plugins/platforms/windows/qwindowscontext.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 783d50a26a..85b03673ac 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -954,7 +954,7 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, qGuiAppPriv->commitData(); if (lParam & ENDSESSION_LOGOFF) - _flushall(); + fflush(NULL); return !sessionManager->wasCanceled(); } -- cgit v1.2.3 From 2cf39c87756ee84dc832958255f01dcdacce1cac Mon Sep 17 00:00:00 2001 From: Kevin Funk Date: Fri, 4 Oct 2013 18:53:30 +0200 Subject: Documentation: Add '\since' to doc for Qt::Edge MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit That enum got introduced in b6e9a8f21ac8b4cc3cc56232ce346ebd7ba17a70 Change-Id: I2d69179624cecff63549bfee66bc68bb4b27af8c Reviewed-by: Topi Reiniö Reviewed-by: Jerome Pasion --- src/corelib/global/qnamespace.qdoc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index f46640ea0e..90f38fd51c 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -1735,6 +1735,8 @@ \value LeftEdge The left edge of the rectangle. \value RightEdge The right edge of the rectangle. \value BottomEdge The bottom edge of the rectangle. + + \since 5.1 */ /*! -- cgit v1.2.3 -- cgit v1.2.3 From 5c87044870752ba9506d7f1d6a0b3de13e72c45f Mon Sep 17 00:00:00 2001 From: Jian Liang Date: Thu, 10 Oct 2013 14:28:22 +0800 Subject: Fix memory leak in QFileInfo::exists() Use the the legacy file engine object created in static function QFileInfo::exists() as the engine of the QFileInfo object to prevent memory leak. This can also boost a little performance. Change-Id: I06317d158d487be5ef15fe3244a917a371563ac9 Reviewed-by: hjk Reviewed-by: Olivier Goffart --- src/corelib/io/qfileinfo.cpp | 3 ++- src/corelib/io/qfileinfo_p.h | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp index 90122a9f0d..1c216f8a6b 100644 --- a/src/corelib/io/qfileinfo.cpp +++ b/src/corelib/io/qfileinfo.cpp @@ -691,7 +691,8 @@ bool QFileInfo::exists(const QString &file) QFileSystemEngine::resolveEntryAndCreateLegacyEngine(entry, data); // Expensive fallback to non-QFileSystemEngine implementation if (engine) - return QFileInfo(file).exists(); + return QFileInfo(new QFileInfoPrivate(entry, data, engine)).exists(); + QFileSystemEngine::fillMetaData(entry, data, QFileSystemMetaData::ExistsAttribute); return data.exists(); } diff --git a/src/corelib/io/qfileinfo_p.h b/src/corelib/io/qfileinfo_p.h index 442e6b5ef0..47359a55ce 100644 --- a/src/corelib/io/qfileinfo_p.h +++ b/src/corelib/io/qfileinfo_p.h @@ -120,6 +120,20 @@ public: metaData = QFileSystemMetaData(); } + inline QFileInfoPrivate(const QFileSystemEntry &file, const QFileSystemMetaData &data, QAbstractFileEngine *engine) + : fileEntry(file), + metaData(data), + fileEngine(engine), + cachedFlags(0), +#ifndef QT_NO_FSFILEENGINE + isDefaultConstructed(false), +#else + isDefaultConstructed(!fileEngine), +#endif + cache_enabled(true), fileFlags(0), fileSize(0) + { + } + inline void clearFlags() const { fileFlags = 0; cachedFlags = 0; -- cgit v1.2.3 From 64332372a133d4c37d3ca8d85c04427386c35300 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Mon, 7 Oct 2013 16:01:53 +0200 Subject: Don't rely on the Qt version when reading a QHeaderView state stream MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since the datastream version is not set in previous versions of Qt when streaming the state of the QHeaderView then we cannot rely on this when adding new data to the state. Therefore we check if we read past the end before assigning to the new variable. Change-Id: I7128ffc91e47f9c8797cfa24d206a789d2814908 Reviewed-by: Thorbjørn Lund Martsum --- src/widgets/itemviews/qheaderview.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp index 123594637a..1131ef030e 100644 --- a/src/widgets/itemviews/qheaderview.cpp +++ b/src/widgets/itemviews/qheaderview.cpp @@ -3693,8 +3693,7 @@ void QHeaderViewPrivate::write(QDataStream &out) const out << int(globalResizeMode); out << sectionItems; - if (out.version() >= QDataStream::Qt_5_2) - out << resizeContentsPrecision; + out << resizeContentsPrecision; } bool QHeaderViewPrivate::read(QDataStream &in) @@ -3747,8 +3746,10 @@ bool QHeaderViewPrivate::read(QDataStream &in) sectionItems = newSectionItems; recalcSectionStartPos(); - if (in.version() >= QDataStream::Qt_5_2) - in >> resizeContentsPrecision; + int tmpint; + in >> tmpint; + if (in.status() == QDataStream::Ok) // we haven't read past end + resizeContentsPrecision = tmpint; return true; } -- cgit v1.2.3 From c81d261080c1814bdda945535cf591ae69d48912 Mon Sep 17 00:00:00 2001 From: Bernd Weimer Date: Fri, 11 Oct 2013 14:37:42 +0200 Subject: QNX: Removed alternate window property MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some older QNX versions don't support SCREEN_PROPERTY_ALTERNATE_WINDOW, so cover windows have generally been disabled on QNX. Change-Id: Ibe4b0abc39eb8497571f88c90876571576708d79 Reviewed-by: Sérgio Martins Reviewed-by: Thomas McGuire --- src/plugins/platforms/qnx/qqnxscreen.cpp | 2 +- src/plugins/platforms/qnx/qqnxwindow.cpp | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/plugins/platforms/qnx/qqnxscreen.cpp b/src/plugins/platforms/qnx/qqnxscreen.cpp index 6c3fd08a41..dd8cf2131a 100644 --- a/src/plugins/platforms/qnx/qqnxscreen.cpp +++ b/src/plugins/platforms/qnx/qqnxscreen.cpp @@ -446,7 +446,7 @@ void QQnxScreen::addWindow(QQnxWindow *window) m_childWindows.push_back(window); updateHierarchy(); } else { -#if !defined(Q_OS_BLACKBERRY_TABLET) +#if defined(Q_OS_BLACKBERRY) && !defined(Q_OS_BLACKBERRY_TABLET) m_coverWindow = window; #endif } diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp index a129380575..3969a09098 100644 --- a/src/plugins/platforms/qnx/qqnxwindow.cpp +++ b/src/plugins/platforms/qnx/qqnxwindow.cpp @@ -562,13 +562,11 @@ void QQnxWindow::initWindow() setScreen(static_cast(window()->screen()->handle())); if (window()->type() == Qt::CoverWindow) { -#if !defined(Q_OS_BLACKBERRY_TABLET) +#if defined(Q_OS_BLACKBERRY) && !defined(Q_OS_BLACKBERRY_TABLET) screen_set_window_property_pv(m_screen->rootWindow()->nativeHandle(), SCREEN_PROPERTY_ALTERNATE_WINDOW, (void**)&m_window); -#if defined(Q_OS_BLACKBERRY) m_cover.reset(new QQnxNavigatorCover); #endif -#endif // Q_OS_BLACKBERRY_TABLET m_exposed = false; } -- cgit v1.2.3 From d004af667d76d43a346dab502c5ccedeafecc29d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 11 Oct 2013 15:50:45 +0200 Subject: macx-xcode: Change wrapper to write to QMAKESPEC to change mkspec The allows us to remove the custom logic in default_post for finding the plist files, and also fixes issues when the wrapped mkspec had its own feature files. Change-Id: I4c26cf6a7809f527e170c51c57f59aaf6088774c Reviewed-by: Oswald Buddenhagen --- mkspecs/macx-xcode/features/default_post.prf | 7 ------- mkspecs/macx-xcode/qmake.conf | 8 +++++++- 2 files changed, 7 insertions(+), 8 deletions(-) delete mode 100644 mkspecs/macx-xcode/features/default_post.prf diff --git a/mkspecs/macx-xcode/features/default_post.prf b/mkspecs/macx-xcode/features/default_post.prf deleted file mode 100644 index 4c4746bb2b..0000000000 --- a/mkspecs/macx-xcode/features/default_post.prf +++ /dev/null @@ -1,7 +0,0 @@ - -isEmpty(QMAKE_INFO_PLIST) { - plist_template = $$absolute_path(../../$$[QMAKE_XSPEC]/Info.plist.$${TEMPLATE}) - exists($$plist_template): QMAKE_INFO_PLIST = $$plist_template -} - -load(default_post) diff --git a/mkspecs/macx-xcode/qmake.conf b/mkspecs/macx-xcode/qmake.conf index bfc1c58935..fde682b64b 100644 --- a/mkspecs/macx-xcode/qmake.conf +++ b/mkspecs/macx-xcode/qmake.conf @@ -4,6 +4,12 @@ # OS X + Xcode # -include(../$$[QMAKE_XSPEC]/qmake.conf) +QMAKESPEC = $$dirname(PWD)/$$[QMAKE_XSPEC] + +include($$QMAKESPEC/qmake.conf) MAKEFILE_GENERATOR = XCODE + +# The active spec is now the original spec, but we still want +# Xcode specific blocks to be triggered. +CONFIG += macx-xcode -- cgit v1.2.3 From 99b20ce0b9316dae0668d71b718bd23eaddbca09 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Thu, 10 Oct 2013 10:47:51 +0200 Subject: Update QPA cursor only for non-synthetic mouse events Unhandled touch events cause QGuiApplication to generate synthetic mouse event by default. This is good but on embedded systems, where there is no windowing system and thus the platform cursor implementation relies solely on QGuiApplication pushing position updates via pointerEvent(), this causes odd behavior when there is both a touchscreen and a mouse present. The patch changes QGuiApplication to call pointerEvent() only when the event is not synthetic. This will prevent the mouse cursor from jumping to the position of the touch when using the touchscreen. It is needed also because moving the mouse later would make the cursor jump back to its previous, "real" mouse position anyhow which is extremely annoying. This is now avoided. Change-Id: I807a173bff7e2afa7eb66961a7ecc88b2c0430ca Reviewed-by: Shawn Rutledge Reviewed-by: Gunnar Sletta --- src/gui/kernel/qguiapplication.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 542b95f58f..1e3ea3092f 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -1566,9 +1566,11 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo QMouseEvent ev(type, localPoint, localPoint, globalPoint, button, buttons, e->modifiers); ev.setTimestamp(e->timestamp); #ifndef QT_NO_CURSOR - if (const QScreen *screen = window->screen()) - if (QPlatformCursor *cursor = screen->handle()->cursor()) - cursor->pointerEvent(ev); + if (!e->synthetic) { + if (const QScreen *screen = window->screen()) + if (QPlatformCursor *cursor = screen->handle()->cursor()) + cursor->pointerEvent(ev); + } #endif if (window->d_func()->blockedByModalWindow) { -- cgit v1.2.3 From a662d42125c5e65166d4f1597a407ec6c351e5d8 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Fri, 11 Oct 2013 13:42:15 +0200 Subject: linuxfb: Pick the correct framebuffer device on Android Try also /dev/graphics/fb0 in addition to /dev/fb0. Change-Id: I9c7682af0c92ebdca806b7c9f60c67d4a732ff41 Reviewed-by: Gunnar Sletta --- src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp index ad5206ba41..0d5bba8457 100644 --- a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp +++ b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp @@ -341,8 +341,15 @@ bool QLinuxFbScreen::initialize(const QStringList &args) userMmSize = QSize(mmSizeRx.cap(1).toInt(), mmSizeRx.cap(2).toInt()); } - if (fbDevice.isEmpty()) - fbDevice = QLatin1String("/dev/fb0"); // ## auto-detect + if (fbDevice.isEmpty()) { + fbDevice = QLatin1String("/dev/fb0"); + if (!QFile::exists(fbDevice)) + fbDevice = QLatin1String("/dev/graphics/fb0"); + if (!QFile::exists(fbDevice)) { + qWarning("Unable to figure out framebuffer device. Specify it manually."); + return false; + } + } // Open the device mFbFd = openFramebufferDevice(fbDevice); -- cgit v1.2.3 From 4ba1072f3f9dff2c674e804eeb998d88510db89c Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Fri, 11 Oct 2013 14:42:14 +0200 Subject: linuxfb: Make the mouse cursor visible and working Change-Id: I58bae7235ae714da551da1337ee6340fc712aaa5 Reviewed-by: Gunnar Sletta --- src/platformsupport/fbconvenience/qfbcursor.cpp | 9 ++++++++- src/platformsupport/fbconvenience/qfbcursor_p.h | 2 +- src/platformsupport/fbconvenience/qfbscreen.cpp | 8 ++++++-- src/platformsupport/fbconvenience/qfbscreen_p.h | 15 +++++++++------ src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp | 18 +++++++++++++++++- 5 files changed, 41 insertions(+), 11 deletions(-) diff --git a/src/platformsupport/fbconvenience/qfbcursor.cpp b/src/platformsupport/fbconvenience/qfbcursor.cpp index fecf9f6380..b86f5830ea 100644 --- a/src/platformsupport/fbconvenience/qfbcursor.cpp +++ b/src/platformsupport/fbconvenience/qfbcursor.cpp @@ -137,5 +137,12 @@ void QFbCursor::changeCursor(QCursor * widgetCursor, QWindow *window) } #endif -QT_END_NAMESPACE +void QFbCursor::setDirty() +{ + if (!mDirty) { + mDirty = true; + mScreen->scheduleUpdate(); + } +} +QT_END_NAMESPACE diff --git a/src/platformsupport/fbconvenience/qfbcursor_p.h b/src/platformsupport/fbconvenience/qfbcursor_p.h index cee9f56ab5..40377e2075 100644 --- a/src/platformsupport/fbconvenience/qfbcursor_p.h +++ b/src/platformsupport/fbconvenience/qfbcursor_p.h @@ -63,7 +63,7 @@ public: virtual void changeCursor(QCursor *widgetCursor, QWindow *window); #endif - virtual void setDirty() { mDirty = true; /* screen->setDirty(QRect()); */ } + virtual void setDirty(); virtual bool isDirty() const { return mDirty; } virtual bool isOnScreen() const { return mOnScreen; } virtual QRect lastPainted() const { return mPrevRect; } diff --git a/src/platformsupport/fbconvenience/qfbscreen.cpp b/src/platformsupport/fbconvenience/qfbscreen.cpp index e5b9f09c14..4ef035cf50 100644 --- a/src/platformsupport/fbconvenience/qfbscreen.cpp +++ b/src/platformsupport/fbconvenience/qfbscreen.cpp @@ -149,9 +149,13 @@ void QFbScreen::setDirty(const QRect &rect) QRect intersection = rect.intersected(mGeometry); QPoint screenOffset = mGeometry.topLeft(); mRepaintRegion += intersection.translated(-screenOffset); // global to local translation - if (!mRedrawTimer.isActive()) { + scheduleUpdate(); +} + +void QFbScreen::scheduleUpdate() +{ + if (!mRedrawTimer.isActive()) mRedrawTimer.start(); - } } void QFbScreen::setPhysicalSize(const QSize &size) diff --git a/src/platformsupport/fbconvenience/qfbscreen_p.h b/src/platformsupport/fbconvenience/qfbscreen_p.h index 01a352e96a..dd940c4a1d 100644 --- a/src/platformsupport/fbconvenience/qfbscreen_p.h +++ b/src/platformsupport/fbconvenience/qfbscreen_p.h @@ -45,6 +45,7 @@ #include #include #include +#include "qfbcursor_p.h" QT_BEGIN_NAMESPACE @@ -60,13 +61,14 @@ public: QFbScreen(); ~QFbScreen(); - virtual QRect geometry() const { return mGeometry; } - virtual int depth() const { return mDepth; } - virtual QImage::Format format() const { return mFormat; } - virtual QSizeF physicalSize() const { return mPhysicalSize; } + QRect geometry() const Q_DECL_OVERRIDE { return mGeometry; } + int depth() const Q_DECL_OVERRIDE { return mDepth; } + QImage::Format format() const Q_DECL_OVERRIDE { return mFormat; } + QSizeF physicalSize() const Q_DECL_OVERRIDE { return mPhysicalSize; } + QPlatformCursor *cursor() const Q_DECL_OVERRIDE { return mCursor; } QWindow *topWindow() const; - virtual QWindow *topLevelAt(const QPoint & p) const; + QWindow *topLevelAt(const QPoint & p) const Q_DECL_OVERRIDE; // compositor api virtual void addWindow(QFbWindow *window); @@ -77,6 +79,8 @@ public: void addBackingStore(QFbBackingStore *bs) {mBackingStores << bs;} + void scheduleUpdate(); + public slots: virtual void setDirty(const QRect &rect); void setPhysicalSize(const QSize &size); @@ -114,4 +118,3 @@ private: QT_END_NAMESPACE #endif // QFBSCREEN_P_H - diff --git a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp index 0d5bba8457..6a2d767723 100644 --- a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp +++ b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp @@ -62,6 +62,10 @@ #include +#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK)) +#include +#endif + QT_BEGIN_NAMESPACE static int openFramebufferDevice(const QString &dev) @@ -394,7 +398,19 @@ bool QLinuxFbScreen::initialize(const QStringList &args) QFbScreen::initializeCompositor(); mFbScreenImage = QImage(mMmap.data, geometry.width(), geometry.height(), mBytesPerLine, mFormat); - mCursor = new QFbCursor(this); + + QByteArray hideCursorVal = qgetenv("QT_QPA_FB_HIDECURSOR"); + bool hideCursor = true; // default to true to prevent the cursor showing up with the subclass on Android + if (hideCursorVal.isEmpty()) { +#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK)) + QScopedPointer dis(QDeviceDiscovery::create(QDeviceDiscovery::Device_Mouse)); + hideCursor = dis->scanConnectedDevices().isEmpty(); +#endif + } else { + hideCursor = hideCursorVal.toInt() != 0; + } + if (!hideCursor) + mCursor = new QFbCursor(this); mTtyFd = openTtyDevice(ttyDevice); if (mTtyFd == -1) -- cgit v1.2.3 From 9ebd76b0214730bfa184008e0a5b2541827912eb Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Fri, 11 Oct 2013 17:59:50 +0200 Subject: Avoid calling convertFromGLImage on a null image. Task-number: QTBUG-34017 Change-Id: If51ef4b1f906677e26d14b5a92799097d18ac437 Reviewed-by: Laszlo Agocs --- src/opengl/qgl.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index c96200fe1b..8ee0a8b290 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -1638,6 +1638,7 @@ QGLContext* QGLContext::currentCtx = 0; static void convertFromGLImage(QImage &img, int w, int h, bool alpha_format, bool include_alpha) { + Q_ASSERT(!img.isNull()); if (QSysInfo::ByteOrder == QSysInfo::BigEndian) { // OpenGL gives RGBA; Qt wants ARGB uint *p = (uint*)img.bits(); @@ -1682,6 +1683,8 @@ QImage qt_gl_read_frame_buffer(const QSize &size, bool alpha_format, bool includ { QImage img(size, (alpha_format && include_alpha) ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32); + if (img.isNull()) + return QImage(); int w = size.width(); int h = size.height(); glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, img.bits()); @@ -1692,6 +1695,8 @@ QImage qt_gl_read_frame_buffer(const QSize &size, bool alpha_format, bool includ QImage qt_gl_read_texture(const QSize &size, bool alpha_format, bool include_alpha) { QImage img(size, alpha_format ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32); + if (img.isNull()) + return QImage(); int w = size.width(); int h = size.height(); #if !defined(QT_OPENGL_ES_2) -- cgit v1.2.3 From f86ffab4023dbba092c7abdf00242f17428d86f5 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Fri, 19 Oct 2012 15:08:42 +0200 Subject: Accessibility: simplify dockwidget accessible This patch merges the two classes that were used to make dock widgets accessible into one. The title bar does not need to be represented by its own accessible object. In addition the buttons on the toolbar are now labelled. Task-number: QTBUG-33946 Change-Id: Id90d8c09f15ed683e64dbe3f6ac55bca7a0b300f Reviewed-by: Frederik Gladhorn --- .../accessible/widgets/qaccessiblewidgets.cpp | 228 ++++----------------- .../accessible/widgets/qaccessiblewidgets.h | 23 +-- src/widgets/widgets/qdockwidget.cpp | 10 +- .../other/qaccessibility/tst_qaccessibility.cpp | 133 +++++++++--- 4 files changed, 144 insertions(+), 250 deletions(-) diff --git a/src/plugins/accessible/widgets/qaccessiblewidgets.cpp b/src/plugins/accessible/widgets/qaccessiblewidgets.cpp index cbb3092b1d..79a5c82fe0 100644 --- a/src/plugins/accessible/widgets/qaccessiblewidgets.cpp +++ b/src/plugins/accessible/widgets/qaccessiblewidgets.cpp @@ -558,37 +558,56 @@ QWidget *QAccessibleCalendarWidget::navigationBar() const #endif // QT_NO_CALENDARWIDGET #ifndef QT_NO_DOCKWIDGET + +// Dock Widget - order of children: +// - Content widget +// - Float button +// - Close button +// If there is a custom title bar widget, that one becomes child 1, after the content 0 +// (in that case the buttons are ignored) QAccessibleDockWidget::QAccessibleDockWidget(QWidget *widget) : QAccessibleWidget(widget, QAccessible::Window) { +} +QDockWidgetLayout *QAccessibleDockWidget::dockWidgetLayout() const +{ + return qobject_cast(dockWidget()->layout()); } -QAccessibleInterface *QAccessibleDockWidget::child(int index) const +int QAccessibleDockWidget::childCount() const { - if (index == 0) { - return new QAccessibleTitleBar(dockWidget()); - } else if (index == 1 && dockWidget()->widget()) { - return QAccessible::queryAccessibleInterface(dockWidget()->widget()); + if (dockWidget()->titleBarWidget()) { + return dockWidget()->widget() ? 2 : 1; } - return 0; + return dockWidgetLayout()->count(); } -int QAccessibleDockWidget::childCount() const +QAccessibleInterface *QAccessibleDockWidget::child(int index) const { - return dockWidget()->widget() ? 2 : 1; + if (dockWidget()->titleBarWidget()) { + if ((!dockWidget()->widget() && index == 0) || (index == 1)) + return QAccessible::queryAccessibleInterface(dockWidget()->titleBarWidget()); + if (index == 0) + return QAccessible::queryAccessibleInterface(dockWidget()->widget()); + } else { + QLayoutItem *item = dockWidgetLayout()->itemAt(index); + if (item) + return QAccessible::queryAccessibleInterface(item->widget()); + } + return 0; } int QAccessibleDockWidget::indexOfChild(const QAccessibleInterface *child) const { - if (child) { - if (child->role() == QAccessible::TitleBar) { - return 0; - } else { - return 1; // FIXME - } + if (!child || !child->object() || child->object()->parent() != object()) + return -1; + + if (dockWidget()->titleBarWidget() == child->object()) { + return dockWidget()->widget() ? 1 : 0; } - return -1; + + return dockWidgetLayout()->indexOf(qobject_cast(child->object())); } QRect QAccessibleDockWidget::rect() const @@ -610,190 +629,13 @@ QDockWidget *QAccessibleDockWidget::dockWidget() const return static_cast(object()); } -//// -// QAccessibleTitleBar -//// -QAccessibleTitleBar::QAccessibleTitleBar(QDockWidget *widget) - : m_dockWidget(widget) -{ - -} - -QAccessibleInterface *QAccessibleTitleBar::parent() const -{ - return new QAccessibleDockWidget(dockWidget()); -} - -QAccessibleInterface *QAccessibleTitleBar::child(int index) const -{ - if (index >= 0) { - QDockWidgetLayout *layout = dockWidgetLayout(); - int role; - int currentIndex = 0; - for (role = QDockWidgetLayout::CloseButton; role <= QDockWidgetLayout::FloatButton; ++role) { - QWidget *w = layout->widgetForRole((QDockWidgetLayout::Role)role); - if (!w || !w->isVisible()) - continue; - if (currentIndex == index) - return QAccessible::queryAccessibleInterface(w); - ++currentIndex; - } - } - return 0; -} - -int QAccessibleTitleBar::indexOfChild(const QAccessibleInterface * /*child*/) const -{ - return -1; -} - -int QAccessibleTitleBar::childCount() const -{ - QDockWidgetLayout *layout = dockWidgetLayout(); - int count = 0; - for (int role = QDockWidgetLayout::CloseButton; role <= QDockWidgetLayout::FloatButton; ++role) { - QWidget *w = layout->widgetForRole((QDockWidgetLayout::Role)role); - if (w && w->isVisible()) - ++count; - } - return count; -} - -QString QAccessibleTitleBar::text(QAccessible::Text t) const +QString QAccessibleDockWidget::text(QAccessible::Text t) const { if (t == QAccessible::Name || t == QAccessible::Value) { return qt_accStripAmp(dockWidget()->windowTitle()); } return QString(); } - -QAccessible::State QAccessibleTitleBar::state() const -{ - QAccessible::State state; - - QDockWidget *w = dockWidget(); - if (w->testAttribute(Qt::WA_WState_Visible) == false) - state.invisible = true; - if (w->focusPolicy() != Qt::NoFocus && w->isActiveWindow()) - state.focusable = true; - if (w->hasFocus()) - state.focused = true; - if (!w->isEnabled()) - state.disabled = true; - - return state; -} - -QRect QAccessibleTitleBar::rect() const -{ - bool mapToGlobal = true; - QRect rect; - - if (dockWidget()->isFloating()) { - rect = dockWidget()->frameGeometry(); - if (dockWidget()->widget()) { - QPoint globalPos = dockWidget()->mapToGlobal(dockWidget()->widget()->rect().topLeft()); - globalPos.ry()--; - rect.setBottom(globalPos.y()); - mapToGlobal = false; - } - } else { - QDockWidgetLayout *layout = qobject_cast(dockWidget()->layout()); - rect = layout->titleArea(); - } - - if (rect.isNull()) - return rect; - - if (mapToGlobal) - rect.moveTopLeft(dockWidget()->mapToGlobal(rect.topLeft())); - return rect; -} - -QAccessibleInterface *QAccessibleTitleBar::childAt(int x, int y) const -{ - for (int i = 0; i < childCount(); ++i) { - QAccessibleInterface *childIface = child(i); - if (childIface->rect().contains(x,y)) { - return childIface; - } - } - return 0; -} - -QObject *QAccessibleTitleBar::object() const -{ - return 0; -} - -QDockWidgetLayout *QAccessibleTitleBar::dockWidgetLayout() const -{ - return qobject_cast(dockWidget()->layout()); -} - -QDockWidget *QAccessibleTitleBar::dockWidget() const -{ - return m_dockWidget; -} - -//QString QAccessibleTitleBar::actionText(int action, Text t, int child) const -//{ -// QString str; -// if (child >= 1 && child <= childCount()) { -// if (t == Name) { -// switch (action) { -// case Press: -// case DefaultAction: -// if (child == QDockWidgetLayout::CloseButton) { -// str = QDockWidget::tr("Close"); -// } else if (child == QDockWidgetLayout::FloatButton) { -// str = dockWidget()->isFloating() ? QDockWidget::tr("Dock") -// : QDockWidget::tr("Float"); -// } -// break; -// default: -// break; -// } -// } -// } -// return str; -//} - -//bool QAccessibleTitleBar::doAction(int action, int child, const QVariantList& /*params*/) -//{ -// if (!child || !dockWidget()->isEnabled()) -// return false; - -// switch (action) { -// case DefaultAction: -// case Press: { -// QDockWidgetLayout *layout = dockWidgetLayout(); -// QAbstractButton *btn = static_cast(layout->widgetForRole((QDockWidgetLayout::Role)child)); -// if (btn) -// btn->animateClick(); -// return true; -// break;} -// default: -// break; -// } - -// return false; -//} - -QAccessible::Role QAccessibleTitleBar::role() const -{ - return QAccessible::TitleBar; -} - -void QAccessibleTitleBar::setText(QAccessible::Text /*t*/, const QString &/*text*/) -{ -} - -bool QAccessibleTitleBar::isValid() const -{ - return dockWidget(); -} - #endif // QT_NO_DOCKWIDGET #ifndef QT_NO_CURSOR diff --git a/src/plugins/accessible/widgets/qaccessiblewidgets.h b/src/plugins/accessible/widgets/qaccessiblewidgets.h index 3e982e82d6..3f50010685 100644 --- a/src/plugins/accessible/widgets/qaccessiblewidgets.h +++ b/src/plugins/accessible/widgets/qaccessiblewidgets.h @@ -283,31 +283,10 @@ public: int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE; int childCount() const Q_DECL_OVERRIDE; QRect rect () const Q_DECL_OVERRIDE; - - QDockWidget *dockWidget() const; -}; - -class QAccessibleTitleBar : public QAccessibleInterface -{ -public: - explicit QAccessibleTitleBar(QDockWidget *widget); - - QAccessibleInterface *parent() const Q_DECL_OVERRIDE; - QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; - int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE; - int childCount() const Q_DECL_OVERRIDE; - QAccessibleInterface *childAt(int x, int y) const Q_DECL_OVERRIDE; - void setText(QAccessible::Text t, const QString &text) Q_DECL_OVERRIDE; QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; - QAccessible::Role role() const Q_DECL_OVERRIDE; - QRect rect () const Q_DECL_OVERRIDE; - QAccessible::State state() const Q_DECL_OVERRIDE; - QObject *object() const Q_DECL_OVERRIDE; - bool isValid() const Q_DECL_OVERRIDE; - - QPointer m_dockWidget; QDockWidget *dockWidget() const; +protected: QDockWidgetLayout *dockWidgetLayout() const; }; diff --git a/src/widgets/widgets/qdockwidget.cpp b/src/widgets/widgets/qdockwidget.cpp index a9b21cbc81..8b151e65bd 100644 --- a/src/widgets/widgets/qdockwidget.cpp +++ b/src/widgets/widgets/qdockwidget.cpp @@ -674,12 +674,18 @@ void QDockWidgetPrivate::updateButtons() = qobject_cast(dwLayout->widgetForRole(QDockWidgetLayout::FloatButton)); button->setIcon(q->style()->standardIcon(QStyle::SP_TitleBarNormalButton, &opt, q)); button->setVisible(canFloat && !hideButtons); - +#ifndef QT_NO_ACCESSIBILITY + button->setAccessibleName(QDockWidget::tr("Float")); + button->setAccessibleDescription(QDockWidget::tr("Undocks and re-attaches the dock widget")); +#endif button = qobject_cast (dwLayout->widgetForRole(QDockWidgetLayout::CloseButton)); button->setIcon(q->style()->standardIcon(QStyle::SP_TitleBarCloseButton, &opt, q)); button->setVisible(canClose && !hideButtons); - +#ifndef QT_NO_ACCESSIBILITY + button->setAccessibleName(QDockWidget::tr("Close")); + button->setAccessibleDescription(QDockWidget::tr("Closes the dock widget")); +#endif q->setAttribute(Qt::WA_ContentsPropagated, (canFloat || canClose) && !hideButtons); diff --git a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp index 092995c0aa..c4a0d9c76c 100644 --- a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp +++ b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp @@ -3056,60 +3056,127 @@ void tst_QAccessibility::dockWidgetTest() mw->setMenuBar(mb); QDockWidget *dock1 = new QDockWidget(mw); + dock1->setWindowTitle("Dock 1"); mw->addDockWidget(Qt::LeftDockWidgetArea, dock1); QPushButton *pb1 = new QPushButton(tr("Push me"), dock1); dock1->setWidget(pb1); QDockWidget *dock2 = new QDockWidget(mw); + dock2->setWindowTitle("Dock 2"); mw->addDockWidget(Qt::BottomDockWidgetArea, dock2); QPushButton *pb2 = new QPushButton(tr("Push me"), dock2); dock2->setWidget(pb2); + dock2->setFeatures(QDockWidget::DockWidgetClosable); mw->resize(600,400); mw->show(); -#if defined(Q_OS_UNIX) - QCoreApplication::processEvents(); - QTest::qWait(100); -#endif + QTest::qWaitForWindowExposed(mw); QAccessibleInterface *accMainWindow = QAccessible::queryAccessibleInterface(mw); // 4 children: menu bar, dock1, dock2, and central widget QCOMPARE(accMainWindow->childCount(), 4); QAccessibleInterface *accDock1 = 0; + QAccessibleInterface *accDock2 = 0; for (int i = 0; i < 4; ++i) { - accDock1 = accMainWindow->child(i); - if (accMainWindow->role() == QAccessible::Window) { - if (accDock1 && qobject_cast(accDock1->object()) == dock1) { - break; - } - } + QAccessibleInterface *child = accMainWindow->child(i); + if (child && child->object() == dock1) + accDock1 = child; + if (child && child->object() == dock2) + accDock2 = child; } + + // Dock widgets consist of + // 0 contents + // 1 close button + // 2 float button QVERIFY(accDock1); QCOMPARE(accDock1->role(), QAccessible::Window); + QCOMPARE(accDock1->text(QAccessible::Name), dock1->windowTitle()); + QCOMPARE(accDock1->childCount(), 3); + + QAccessibleInterface *dock1Widget = accDock1->child(0); + QCOMPARE(dock1Widget->role(), QAccessible::Button); + QCOMPARE(dock1Widget->text(QAccessible::Name), pb1->text()); + +#ifdef Q_OS_MAC + QEXPECT_FAIL("", "Dock Widget geometry on Mac seems broken.", Continue); +#endif + QVERIFY(accDock1->rect().contains(dock1Widget->rect())); + QCOMPARE(accDock1->indexOfChild(dock1Widget), 0); + QCOMPARE(dock1Widget->parent()->object(), dock1); + + QAccessibleInterface *dock1Close = accDock1->child(1); + QCOMPARE(dock1Close->role(), QAccessible::Button); + QCOMPARE(dock1Close->text(QAccessible::Name), QDockWidget::tr("Close")); + QVERIFY(accDock1->rect().contains(dock1Close->rect())); + QCOMPARE(accDock1->indexOfChild(dock1Close), 1); + QCOMPARE(dock1Close->parent()->object(), dock1); + + QAccessibleInterface *dock1Float = accDock1->child(2); + QCOMPARE(dock1Float->role(), QAccessible::Button); + QCOMPARE(dock1Float->text(QAccessible::Name), QDockWidget::tr("Float")); + QVERIFY(accDock1->rect().contains(dock1Float->rect())); + QCOMPARE(accDock1->indexOfChild(dock1Float), 2); + QVERIFY(!dock1Float->state().invisible); + + QVERIFY(accDock2); + QCOMPARE(accDock2->role(), QAccessible::Window); + QCOMPARE(accDock2->text(QAccessible::Name), dock2->windowTitle()); + QCOMPARE(accDock2->childCount(), 3); + + QAccessibleInterface *dock2Widget = accDock2->child(0); + QCOMPARE(dock2Widget->role(), QAccessible::Button); + QCOMPARE(dock2Widget->text(QAccessible::Name), pb1->text()); +#ifdef Q_OS_MAC + QEXPECT_FAIL("", "Dock Widget geometry on Mac seems broken.", Continue); +#endif + QVERIFY(accDock2->rect().contains(dock2Widget->rect())); + QCOMPARE(accDock2->indexOfChild(dock2Widget), 0); + + QAccessibleInterface *dock2Close = accDock2->child(1); + QCOMPARE(dock2Close->role(), QAccessible::Button); + QCOMPARE(dock2Close->text(QAccessible::Name), QDockWidget::tr("Close")); + QVERIFY(accDock2->rect().contains(dock2Close->rect())); + QCOMPARE(accDock2->indexOfChild(dock2Close), 1); + QVERIFY(!dock2Close->state().invisible); + + QAccessibleInterface *dock2Float = accDock2->child(2); + QCOMPARE(dock2Float->role(), QAccessible::Button); + QCOMPARE(dock2Float->text(QAccessible::Name), QDockWidget::tr("Float")); + QCOMPARE(accDock2->indexOfChild(dock2Float), 2); + QVERIFY(dock2Float->state().invisible); + + QPoint buttonPoint = pb2->mapToGlobal(QPoint(pb2->width()/2, pb2->height()/2)); + QAccessibleInterface *childAt = accDock2->childAt(buttonPoint.x(), buttonPoint.y()); + QVERIFY(childAt); + QVERIFY(childAt->object() == pb2); + + QWidget *close1 = qobject_cast(dock1Close->object()); + QPoint close1ButtonPoint = close1->mapToGlobal(QPoint(close1->width()/2, close1->height()/2)); + QAccessibleInterface *childAt2 = accDock1->childAt(close1ButtonPoint.x(), close1ButtonPoint.y()); + QVERIFY(childAt2); + QVERIFY(childAt2->object() == close1); + + // custom title bar widget + QDockWidget *dock3 = new QDockWidget(mw); + dock3->setWindowTitle("Dock 3"); + mw->addDockWidget(Qt::LeftDockWidgetArea, dock3); + QPushButton *pb3 = new QPushButton(tr("Push me"), dock3); + dock3->setWidget(pb3); + QLabel *titleLabel = new QLabel("I am a title widget"); + dock3->setTitleBarWidget(titleLabel); + + QAccessibleInterface *accDock3 = accMainWindow->child(4); + QVERIFY(accDock3); + QCOMPARE(accDock3->role(), QAccessible::Window); + QCOMPARE(accDock3->text(QAccessible::Name), dock3->windowTitle()); + QCOMPARE(accDock3->childCount(), 2); + QAccessibleInterface *titleWidget = accDock3->child(1); + QVERIFY(titleWidget); + QCOMPARE(titleWidget->text(QAccessible::Name), titleLabel->text()); + QAccessibleInterface *dock3Widget = accDock3->child(0); + QCOMPARE(dock3Widget->text(QAccessible::Name), pb3->text()); - QAccessibleInterface *dock1TitleBar = accDock1->child(0); - QCOMPARE(dock1TitleBar->role(), QAccessible::TitleBar); - QVERIFY(accDock1->rect().contains(dock1TitleBar->rect())); - - QPoint globalPos = dock1->mapToGlobal(QPoint(0,0)); - globalPos.rx()+=5; //### query style - globalPos.ry()+=5; - QAccessibleInterface *childAt = accDock1->childAt(globalPos.x(), globalPos.y()); //### - QCOMPARE(childAt->role(), QAccessible::TitleBar); - int index = accDock1->indexOfChild(childAt); - QAccessibleInterface *accTitleBar = accDock1->child(index); - - QCOMPARE(accTitleBar->role(), QAccessible::TitleBar); - QCOMPARE(accDock1->indexOfChild(accTitleBar), 0); - QAccessibleInterface *acc; - acc = accTitleBar->parent(); - QVERIFY(acc); - QCOMPARE(acc->role(), QAccessible::Window); - - delete pb1; - delete pb2; - delete dock1; - delete dock2; delete mw; QTestAccessibility::clearEvents(); #endif // QT_NO_DOCKWIDGET -- cgit v1.2.3 From 17ebcd2b4690f73c8fd2332b0ba55b3ee3e2e8bb Mon Sep 17 00:00:00 2001 From: Arthur Krebsbach Date: Tue, 8 Oct 2013 08:51:23 -0700 Subject: Windows: Fix tablet position in relative (mouse) mode. When in "mouse" or "relative" mode with the pen position information would not be calculated correctly resulting in a significant offset between the tablet pen location and the mouse cursor location. Logic was added to detect when the two were not in sync and use the mouse location when this happens. Change-Id: Icb7129e8cce186c0099953769e215649d9347c8e Reviewed-by: Laszlo Agocs --- .../platforms/windows/qwindowstabletsupport.cpp | 33 +++++++++++++++++++--- .../platforms/windows/qwindowstabletsupport.h | 1 + 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowstabletsupport.cpp b/src/plugins/platforms/windows/qwindowstabletsupport.cpp index 4a5d7b5a78..1a5c1a2e0c 100644 --- a/src/plugins/platforms/windows/qwindowstabletsupport.cpp +++ b/src/plugins/platforms/windows/qwindowstabletsupport.cpp @@ -395,8 +395,19 @@ bool QWindowsTabletSupport::translateTabletPacketEvent() const int currentDevice = m_devices.at(m_currentDevice).currentDevice; const int currentPointer = m_devices.at(m_currentDevice).currentPointerType; - // When entering proximity, the tablet driver snaps the mouse pointer to the - // tablet position scaled to the virtual desktop and keeps it in sync. + // The tablet can be used in 2 different modes, depending on it settings: + // 1) Absolute (pen) mode: + // The coordinates are scaled to the virtual desktop (by default). The user + // can also choose to scale to the monitor or a region of the screen. + // When entering proximity, the tablet driver snaps the mouse pointer to the + // tablet position scaled to that area and keeps it in sync. + // 2) Relative (mouse) mode: + // The pen follows the mouse. The constant 'absoluteRange' specifies the + // manhattanLength difference for detecting if a tablet input device is in this mode, + // in which case we snap the position to the mouse position. + // It seems there is no way to find out the mode programmatically, the LOGCONTEXT orgX/Y/Ext + // area is always the virtual desktop. + enum { absoluteRange = 20 }; const QRect virtualDesktopArea = QGuiApplication::primaryScreen()->virtualGeometry(); if (QWindowsContext::verboseTablet) @@ -409,10 +420,24 @@ bool QWindowsTabletSupport::translateTabletPacketEvent() const PACKET &packet = localPacketBuf[i]; const int z = currentDevice == QTabletEvent::FourDMouse ? int(packet.pkZ) : 0; - const QPointF globalPosF = m_devices.at(m_currentDevice).scaleCoordinates(packet.pkX, packet.pkY, virtualDesktopArea); + + // This code is to delay the tablet data one cycle to sync with the mouse location. + QPointF globalPosF = m_oldGlobalPosF; + m_oldGlobalPosF = m_devices.at(m_currentDevice).scaleCoordinates(packet.pkX, packet.pkY, virtualDesktopArea); QWindow *target = QGuiApplicationPrivate::tabletPressTarget; // Pass to window that grabbed it. - const QPoint globalPos = globalPosF.toPoint(); + QPoint globalPos = globalPosF.toPoint(); + + // Get Mouse Position and compare to tablet info + const QPoint mouseLocation = QWindowsCursor::mousePosition(); + + // Positions should be almost the same if we are in absolute + // mode. If they are not, use the mouse location. + if ((mouseLocation - globalPos).manhattanLength() > absoluteRange) { + globalPos = mouseLocation; + globalPosF = globalPos; + } + if (!target) if (QPlatformWindow *pw = QWindowsContext::instance()->findPlatformWindowAt(GetDesktopWindow(), globalPos, CWP_SKIPINVISIBLE | CWP_SKIPTRANSPARENT)) target = pw->window(); diff --git a/src/plugins/platforms/windows/qwindowstabletsupport.h b/src/plugins/platforms/windows/qwindowstabletsupport.h index 12f96b618d..5e29cd9554 100644 --- a/src/plugins/platforms/windows/qwindowstabletsupport.h +++ b/src/plugins/platforms/windows/qwindowstabletsupport.h @@ -134,6 +134,7 @@ private: bool m_tiltSupport; QVector m_devices; int m_currentDevice; + QPointF m_oldGlobalPosF; }; QT_END_NAMESPACE -- cgit v1.2.3 From 401510dbbec40b5c6350bb8a9be3ab92292dbc3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 11 Oct 2013 12:56:06 +0200 Subject: iOS: Move qmake features out of the generic features and into the makespec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As they are closely tied to the macx-ios-clang mkspec and can't be shared. Change-Id: Icb59304cc1e4be12732f50175f3f84be289300c2 Reviewed-by: Tor Arne Vestbø --- mkspecs/features/ios/default_post.prf | 85 ------------------------ mkspecs/features/ios/default_pre.prf | 9 --- mkspecs/features/ios/qt.prf | 75 --------------------- mkspecs/macx-ios-clang/features/default_post.prf | 85 ++++++++++++++++++++++++ mkspecs/macx-ios-clang/features/default_pre.prf | 9 +++ mkspecs/macx-ios-clang/features/qt.prf | 75 +++++++++++++++++++++ 6 files changed, 169 insertions(+), 169 deletions(-) delete mode 100644 mkspecs/features/ios/default_post.prf delete mode 100644 mkspecs/features/ios/default_pre.prf delete mode 100644 mkspecs/features/ios/qt.prf create mode 100644 mkspecs/macx-ios-clang/features/default_post.prf create mode 100644 mkspecs/macx-ios-clang/features/default_pre.prf create mode 100644 mkspecs/macx-ios-clang/features/qt.prf diff --git a/mkspecs/features/ios/default_post.prf b/mkspecs/features/ios/default_post.prf deleted file mode 100644 index a61db3daea..0000000000 --- a/mkspecs/features/ios/default_post.prf +++ /dev/null @@ -1,85 +0,0 @@ - -equals(TEMPLATE, app) { - - # If the application uses Qt, it needs to be an application bundle - # to be able to deploy and run on iOS. The only exception to this - # is if you're working with a jailbroken device and can run the - # resulting binary from the console/over SSH, but that's not a - # use-case we care about, so no need to complicate the logic. - qt: CONFIG *= app_bundle - - # Application bundles require building through Xcode - app_bundle:!macx-xcode { - # For Qt applications we want Xcode project files as the generated output, - # but since qmake doesn't handle the transition between makefiles and Xcode - # project files (which happens when using subdirs), we create a wrapper - # makefile that takes care of generating the Xcode project, and allows - # building by calling out to xcodebuild. - TEMPLATE = aux - - CONFIG -= have_target qt staticlib dll - SOURCES = - RESOURCES = - INSTALLS = - - TARGET_XCODE_PROJECT_DIR = $${TARGET}.xcodeproj - - system("cd $$system_quote($$OUT_PWD) && $${QMAKE_QMAKE} $$system_quote($$_PRO_FILE_) -spec macx-xcode") - - # We use xcodebuild to do the actual build, but filter out the verbose - # output that shows all environment variables for each build step. - xcodebuild_build.commands = "@bash -o pipefail -c 'xcodebuild | grep -v setenv'" - QMAKE_EXTRA_TARGETS += xcodebuild_build - all.depends = xcodebuild_build - QMAKE_EXTRA_TARGETS += all - - # We do the same for the clean action - xcodebuild_clean.commands = "@xcodebuild clean" - QMAKE_EXTRA_TARGETS += xcodebuild_clean - clean.depends = xcodebuild_clean - QMAKE_EXTRA_TARGETS += clean - - # And distclean - xcodebuild_distclean.commands = "$(DEL_FILE) -R $$TARGET_XCODE_PROJECT_DIR" - QMAKE_EXTRA_TARGETS += xcodebuild_distclean - distclean.depends = xcodebuild_distclean - QMAKE_EXTRA_TARGETS += distclean - } -} - -macx-xcode { - ios_device_family.name = TARGETED_DEVICE_FAMILY - ios_device_family.value = $$QMAKE_IOS_TARGETED_DEVICE_FAMILY - QMAKE_MAC_XCODE_SETTINGS += ios_device_family -} - -isEmpty(QT_ARCH) { - # The iPhoneOS and iPhoneSimulator targets share the same toolchain, - # so when configure runs the arch tests it passes the correct sysroot, - # but we fail to pick up the architecture since we're not passing -arch - # yet. Xcode does not seem to have a way to run the shared toolchain - # in a way that will automatically do this (for example xcrun -sdk). - contains(QMAKE_MAC_SDK, iphoneos.*): QT_ARCH = arm - else: QT_ARCH = i386 # Simulator -} - -# Be more specific about which architecture we're targeting -equals(QT_ARCH, arm): \ - actual_archs = armv7 -else: \ - actual_archs = $$QT_ARCH - -macx-xcode { - QMAKE_XCODE_ARCHS = $$actual_archs -} else { - for(arch, actual_archs): \ - arch_flags += -arch $$arch - - QMAKE_CFLAGS += $$arch_flags - QMAKE_CXXFLAGS += $$arch_flags - QMAKE_OBJECTIVE_CFLAGS += $$arch_flags - QMAKE_LFLAGS += $$arch_flags -} -unset(actual_archs) - -load(default_post) diff --git a/mkspecs/features/ios/default_pre.prf b/mkspecs/features/ios/default_pre.prf deleted file mode 100644 index de5a9170d7..0000000000 --- a/mkspecs/features/ios/default_pre.prf +++ /dev/null @@ -1,9 +0,0 @@ - -load(default_pre) - -# Check for supported Xcode versions -lessThan(QMAKE_XCODE_VERSION, "4.3"): \ - error("This mkspec requires Xcode 4.3 or later") -!contains(QMAKE_XCODE_VERSION, ^(4\\.[3456]|5\\.[0])$): \ - warning("The version of Xcode installed on this system ($$QMAKE_XCODE_VERSION)" \ - "has not been tested fully - custom compiler settings may be necessary") diff --git a/mkspecs/features/ios/qt.prf b/mkspecs/features/ios/qt.prf deleted file mode 100644 index 9fa882c99f..0000000000 --- a/mkspecs/features/ios/qt.prf +++ /dev/null @@ -1,75 +0,0 @@ - -equals(TEMPLATE, app):contains(QT, gui(-private)?) { - !macx-xcode: \ - error("Linking the iOS platform plugin requires bulding through Xcode") - - LIBS *= -L$$[QT_INSTALL_PLUGINS/get]/platforms - - lib_name = qios - lib_path_and_base = $$[QT_INSTALL_PLUGINS/get]/platforms/lib$${lib_name}$$qtPlatformTargetSuffix() - LIBS += -l$${lib_name}$$qtPlatformTargetSuffix() $$fromfile($${lib_path_and_base}.prl, QMAKE_PRL_LIBS) - - # By marking qt_registerPlatformPlugin as undefined, we ensure that - # the plugin.o translation unit is considered for inclusion in - # the final binary, which in turn ensures that the plugin's - # static initializer is included and run. - QMAKE_LFLAGS += -u _qt_registerPlatformPlugin - - # We do link and dependency resolution for the platform plugin - # manually, since we know we always need the plugin, so we don't - # need to generate an import for it. - CONFIG -= import_qpa_plugin - - !no_main_wrapper { - # Instead of messing with the user's main function we go the other - # way and change the application entry point to call our main wrapper. - # This entry point is the 'start' symbol, provided by crt1.o, so we - # make a copy of the file and rename the '_main' unresolved symbol - # to our wrapper function, '_qtmn', injecting ourselves into the app - # startup. Once Apple starts shipping the LLVM linker (lld) we may - # get rid of this step completely and just pass -e _qtmn to the - # linker, taking advantage of the new LC_MAIN load command. - - # We know that iOS 3.1 and up uses crt1.3.1.o (technically not - # true for simulator, but the SDK has a symlink to the correct file). - original_crt_path = "$(SDK_DIR)/usr/lib/crt1.3.1.o" - - xcode_objects_path = "$(OBJECT_FILE_DIR_$(CURRENT_VARIANT))/$(CURRENT_ARCH)" - custom_crt_filename = "crt1_qt.o" - custom_crt_path = "$$xcode_objects_path/$$custom_crt_filename" - - EOC = $$escape_expand(\\n\\t) - create_custom_crt.commands = \ - # Copy original crt1 to build directory - "$$QMAKE_COPY_FILE $$original_crt_path $$custom_crt_path $$EOC" \ - # And rename all occurrences of _main to _qtmn - "strings -t d - $${custom_crt_path}" \ - "| sed -n 's/^\\([0-9]\\{1,\\}\\) _main\$\$/\1/p'" \ - "| while read offset; do" \ - "printf '_qtmn'" \ - "| dd of=$${custom_crt_path} bs=1 seek=\$\$offset conv=notrunc >/dev/null 2>&1" \ - "; done" - create_custom_crt.depends = $$original_crt_path - create_custom_crt.target = $$custom_crt_path - preprocess.depends = create_custom_crt - QMAKE_EXTRA_TARGETS += create_custom_crt preprocess - - clean_custom_crt.commands = "$$QMAKE_DEL_FILE $$custom_crt_path" - preprocess_clean.depends += clean_custom_crt - QMAKE_EXTRA_TARGETS += clean_custom_crt preprocess_clean - - # Prevent usage of new LC_MAIN load command, which skips start/crt1 - # and calls main from the loader. We rely on injecting into start. - QMAKE_LFLAGS += -Wl,-no_new_main - - # Explicitly link against our modified crt1 object - QMAKE_LFLAGS += -nostartfiles -l$${custom_crt_filename} - - # Workaround for QMAKE_PBX_LIBPATHS mangling the Xcode variables - lib_search_path.name = LIBRARY_SEARCH_PATHS - lib_search_path.value = $$xcode_objects_path - QMAKE_MAC_XCODE_SETTINGS += lib_search_path - } -} - -load(qt) diff --git a/mkspecs/macx-ios-clang/features/default_post.prf b/mkspecs/macx-ios-clang/features/default_post.prf new file mode 100644 index 0000000000..a61db3daea --- /dev/null +++ b/mkspecs/macx-ios-clang/features/default_post.prf @@ -0,0 +1,85 @@ + +equals(TEMPLATE, app) { + + # If the application uses Qt, it needs to be an application bundle + # to be able to deploy and run on iOS. The only exception to this + # is if you're working with a jailbroken device and can run the + # resulting binary from the console/over SSH, but that's not a + # use-case we care about, so no need to complicate the logic. + qt: CONFIG *= app_bundle + + # Application bundles require building through Xcode + app_bundle:!macx-xcode { + # For Qt applications we want Xcode project files as the generated output, + # but since qmake doesn't handle the transition between makefiles and Xcode + # project files (which happens when using subdirs), we create a wrapper + # makefile that takes care of generating the Xcode project, and allows + # building by calling out to xcodebuild. + TEMPLATE = aux + + CONFIG -= have_target qt staticlib dll + SOURCES = + RESOURCES = + INSTALLS = + + TARGET_XCODE_PROJECT_DIR = $${TARGET}.xcodeproj + + system("cd $$system_quote($$OUT_PWD) && $${QMAKE_QMAKE} $$system_quote($$_PRO_FILE_) -spec macx-xcode") + + # We use xcodebuild to do the actual build, but filter out the verbose + # output that shows all environment variables for each build step. + xcodebuild_build.commands = "@bash -o pipefail -c 'xcodebuild | grep -v setenv'" + QMAKE_EXTRA_TARGETS += xcodebuild_build + all.depends = xcodebuild_build + QMAKE_EXTRA_TARGETS += all + + # We do the same for the clean action + xcodebuild_clean.commands = "@xcodebuild clean" + QMAKE_EXTRA_TARGETS += xcodebuild_clean + clean.depends = xcodebuild_clean + QMAKE_EXTRA_TARGETS += clean + + # And distclean + xcodebuild_distclean.commands = "$(DEL_FILE) -R $$TARGET_XCODE_PROJECT_DIR" + QMAKE_EXTRA_TARGETS += xcodebuild_distclean + distclean.depends = xcodebuild_distclean + QMAKE_EXTRA_TARGETS += distclean + } +} + +macx-xcode { + ios_device_family.name = TARGETED_DEVICE_FAMILY + ios_device_family.value = $$QMAKE_IOS_TARGETED_DEVICE_FAMILY + QMAKE_MAC_XCODE_SETTINGS += ios_device_family +} + +isEmpty(QT_ARCH) { + # The iPhoneOS and iPhoneSimulator targets share the same toolchain, + # so when configure runs the arch tests it passes the correct sysroot, + # but we fail to pick up the architecture since we're not passing -arch + # yet. Xcode does not seem to have a way to run the shared toolchain + # in a way that will automatically do this (for example xcrun -sdk). + contains(QMAKE_MAC_SDK, iphoneos.*): QT_ARCH = arm + else: QT_ARCH = i386 # Simulator +} + +# Be more specific about which architecture we're targeting +equals(QT_ARCH, arm): \ + actual_archs = armv7 +else: \ + actual_archs = $$QT_ARCH + +macx-xcode { + QMAKE_XCODE_ARCHS = $$actual_archs +} else { + for(arch, actual_archs): \ + arch_flags += -arch $$arch + + QMAKE_CFLAGS += $$arch_flags + QMAKE_CXXFLAGS += $$arch_flags + QMAKE_OBJECTIVE_CFLAGS += $$arch_flags + QMAKE_LFLAGS += $$arch_flags +} +unset(actual_archs) + +load(default_post) diff --git a/mkspecs/macx-ios-clang/features/default_pre.prf b/mkspecs/macx-ios-clang/features/default_pre.prf new file mode 100644 index 0000000000..de5a9170d7 --- /dev/null +++ b/mkspecs/macx-ios-clang/features/default_pre.prf @@ -0,0 +1,9 @@ + +load(default_pre) + +# Check for supported Xcode versions +lessThan(QMAKE_XCODE_VERSION, "4.3"): \ + error("This mkspec requires Xcode 4.3 or later") +!contains(QMAKE_XCODE_VERSION, ^(4\\.[3456]|5\\.[0])$): \ + warning("The version of Xcode installed on this system ($$QMAKE_XCODE_VERSION)" \ + "has not been tested fully - custom compiler settings may be necessary") diff --git a/mkspecs/macx-ios-clang/features/qt.prf b/mkspecs/macx-ios-clang/features/qt.prf new file mode 100644 index 0000000000..9fa882c99f --- /dev/null +++ b/mkspecs/macx-ios-clang/features/qt.prf @@ -0,0 +1,75 @@ + +equals(TEMPLATE, app):contains(QT, gui(-private)?) { + !macx-xcode: \ + error("Linking the iOS platform plugin requires bulding through Xcode") + + LIBS *= -L$$[QT_INSTALL_PLUGINS/get]/platforms + + lib_name = qios + lib_path_and_base = $$[QT_INSTALL_PLUGINS/get]/platforms/lib$${lib_name}$$qtPlatformTargetSuffix() + LIBS += -l$${lib_name}$$qtPlatformTargetSuffix() $$fromfile($${lib_path_and_base}.prl, QMAKE_PRL_LIBS) + + # By marking qt_registerPlatformPlugin as undefined, we ensure that + # the plugin.o translation unit is considered for inclusion in + # the final binary, which in turn ensures that the plugin's + # static initializer is included and run. + QMAKE_LFLAGS += -u _qt_registerPlatformPlugin + + # We do link and dependency resolution for the platform plugin + # manually, since we know we always need the plugin, so we don't + # need to generate an import for it. + CONFIG -= import_qpa_plugin + + !no_main_wrapper { + # Instead of messing with the user's main function we go the other + # way and change the application entry point to call our main wrapper. + # This entry point is the 'start' symbol, provided by crt1.o, so we + # make a copy of the file and rename the '_main' unresolved symbol + # to our wrapper function, '_qtmn', injecting ourselves into the app + # startup. Once Apple starts shipping the LLVM linker (lld) we may + # get rid of this step completely and just pass -e _qtmn to the + # linker, taking advantage of the new LC_MAIN load command. + + # We know that iOS 3.1 and up uses crt1.3.1.o (technically not + # true for simulator, but the SDK has a symlink to the correct file). + original_crt_path = "$(SDK_DIR)/usr/lib/crt1.3.1.o" + + xcode_objects_path = "$(OBJECT_FILE_DIR_$(CURRENT_VARIANT))/$(CURRENT_ARCH)" + custom_crt_filename = "crt1_qt.o" + custom_crt_path = "$$xcode_objects_path/$$custom_crt_filename" + + EOC = $$escape_expand(\\n\\t) + create_custom_crt.commands = \ + # Copy original crt1 to build directory + "$$QMAKE_COPY_FILE $$original_crt_path $$custom_crt_path $$EOC" \ + # And rename all occurrences of _main to _qtmn + "strings -t d - $${custom_crt_path}" \ + "| sed -n 's/^\\([0-9]\\{1,\\}\\) _main\$\$/\1/p'" \ + "| while read offset; do" \ + "printf '_qtmn'" \ + "| dd of=$${custom_crt_path} bs=1 seek=\$\$offset conv=notrunc >/dev/null 2>&1" \ + "; done" + create_custom_crt.depends = $$original_crt_path + create_custom_crt.target = $$custom_crt_path + preprocess.depends = create_custom_crt + QMAKE_EXTRA_TARGETS += create_custom_crt preprocess + + clean_custom_crt.commands = "$$QMAKE_DEL_FILE $$custom_crt_path" + preprocess_clean.depends += clean_custom_crt + QMAKE_EXTRA_TARGETS += clean_custom_crt preprocess_clean + + # Prevent usage of new LC_MAIN load command, which skips start/crt1 + # and calls main from the loader. We rely on injecting into start. + QMAKE_LFLAGS += -Wl,-no_new_main + + # Explicitly link against our modified crt1 object + QMAKE_LFLAGS += -nostartfiles -l$${custom_crt_filename} + + # Workaround for QMAKE_PBX_LIBPATHS mangling the Xcode variables + lib_search_path.name = LIBRARY_SEARCH_PATHS + lib_search_path.value = $$xcode_objects_path + QMAKE_MAC_XCODE_SETTINGS += lib_search_path + } +} + +load(qt) -- cgit v1.2.3 From 535e3567496caa317221a786486968a424f5faa8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 14 Oct 2013 13:52:49 +0200 Subject: iOS: Remove check for unknown Xcode versions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We assume new Xcode versions and toolchains won't break anything, just like for toolchains on other platforms. Change-Id: Idb723dbcdbc82e85db1c55b19cd5fe863ca90933 Reviewed-by: Tor Arne Vestbø --- mkspecs/macx-ios-clang/features/default_pre.prf | 3 --- 1 file changed, 3 deletions(-) diff --git a/mkspecs/macx-ios-clang/features/default_pre.prf b/mkspecs/macx-ios-clang/features/default_pre.prf index de5a9170d7..b37f67495c 100644 --- a/mkspecs/macx-ios-clang/features/default_pre.prf +++ b/mkspecs/macx-ios-clang/features/default_pre.prf @@ -4,6 +4,3 @@ load(default_pre) # Check for supported Xcode versions lessThan(QMAKE_XCODE_VERSION, "4.3"): \ error("This mkspec requires Xcode 4.3 or later") -!contains(QMAKE_XCODE_VERSION, ^(4\\.[3456]|5\\.[0])$): \ - warning("The version of Xcode installed on this system ($$QMAKE_XCODE_VERSION)" \ - "has not been tested fully - custom compiler settings may be necessary") -- cgit v1.2.3 From 12b68ed072f290c2c148a3241d25107ffa34102a Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 14 Oct 2013 16:52:34 +0300 Subject: Stabilize tst_qmenu on Mac. Position cursor outside and move once more. Task-number: QTBUG-33972 Change-Id: If060f1359361981cf1243d8d2a4ebef181689d74 Reviewed-by: Gabriel de Dietrich --- tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp index 3c32b8a476..7c1bb957d6 100644 --- a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp +++ b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp @@ -764,14 +764,20 @@ void tst_QMenu::task258920_mouseBorder() menu.setMouseTracking(true); QAction *action = menu.addAction("test"); - menu.popup(QApplication::desktop()->availableGeometry().center()); + const QPoint center = QApplication::desktop()->availableGeometry().center(); +#ifndef QT_NO_CURSOR + QCursor::setPos(center - QPoint(100, 100)); // Mac: Ensure cursor is outside +#endif + menu.popup(center); QVERIFY(QTest::qWaitForWindowExposed(&menu)); QTest::qWait(100); QRect actionRect = menu.actionGeometry(action); - QTest::mouseMove(&menu, actionRect.center()); + const QPoint actionCenter = actionRect.center(); + QTest::mouseMove(&menu, actionCenter - QPoint(-10, 0)); QTest::qWait(30); - QTest::mouseMove(&menu, actionRect.center() + QPoint(10, 0)); + QTest::mouseMove(&menu, actionCenter); QTest::qWait(30); + QTest::mouseMove(&menu, actionCenter + QPoint(10, 0)); QTRY_COMPARE(action, menu.activeAction()); menu.painted = false; QTest::mouseMove(&menu, QPoint(actionRect.center().x(), actionRect.bottom() + 1)); -- cgit v1.2.3 From 4c8f194adee41d954bae4bb1c62b3a2591d86630 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 10 Oct 2013 16:22:36 +0200 Subject: Fix synqt-warnings in QTestLib. QtTest: WARNING: qtestmouse.h includes QDebug when it should include QtCore/QDebug. Introduced by c2106683461bc02da95f7bd014eca17beeec4319 . Change-Id: I33918c82fddeedef90597bf02c93167348d6b279 Reviewed-by: Stephen Kelly --- src/testlib/qtestmouse.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/testlib/qtestmouse.h b/src/testlib/qtestmouse.h index 8efa80789c..a07d6bc8c6 100644 --- a/src/testlib/qtestmouse.h +++ b/src/testlib/qtestmouse.h @@ -61,7 +61,7 @@ #include #endif -#include +#include QT_BEGIN_NAMESPACE -- cgit v1.2.3 From 2c7ad71adbdb00924b3d7797339dbcf8d6d86479 Mon Sep 17 00:00:00 2001 From: Harri Porten Date: Mon, 14 Oct 2013 16:49:07 +0200 Subject: Fixed narrowing conversion compile error with SwizzleValue cast. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I got the following compile error with gcc 4.7.0: error: narrowing conversion of ‘r’ from ‘QOpenGLTexture::SwizzleValue’ to ‘GLint {aka int}’ inside { } [-Werror=narrowing] The compiler must being going through the route of treating the enum as an unsigned int and thus choking on the conversion to a signed int. Change-Id: I35c15673d0371c69984bdec80622066f792527ba Reviewed-by: Sean Harmer Reviewed-by: Thiago Macieira --- src/gui/opengl/qopengltexture.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/opengl/qopengltexture.cpp b/src/gui/opengl/qopengltexture.cpp index fcd556e892..d5a7399c18 100644 --- a/src/gui/opengl/qopengltexture.cpp +++ b/src/gui/opengl/qopengltexture.cpp @@ -2488,7 +2488,7 @@ void QOpenGLTexture::setSwizzleMask(SwizzleValue r, SwizzleValue g, qWarning("QOpenGLTexture::setSwizzleMask() requires OpenGL >= 3.3"); return; } - GLint swizzleMask[] = {r, g, b, a}; + GLint swizzleMask[] = {GLint(r), GLint(g), GLint(b), GLint(a)}; d->swizzleMask[0] = r; d->swizzleMask[1] = g; d->swizzleMask[2] = b; -- cgit v1.2.3 From fe1cbe9ca78619b54b08e4ec1155d7e6e4e0640a Mon Sep 17 00:00:00 2001 From: Laszlo Papp Date: Thu, 3 Oct 2013 23:17:34 +0100 Subject: Add qWarning when trying to read or write a closed device Change-Id: Ifda057d122a30d88749c6401185457f1900a913b Reviewed-by: Oswald Buddenhagen Reviewed-by: Richard J. Moore Reviewed-by: Lars Knoll Reviewed-by: Thiago Macieira --- src/corelib/io/qiodevice.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp index 8fb80123fa..a81b8580c4 100644 --- a/src/corelib/io/qiodevice.cpp +++ b/src/corelib/io/qiodevice.cpp @@ -99,8 +99,10 @@ void debugBinaryString(const char *data, qint64 maxlen) #define CHECK_WRITABLE(function, returnType) \ do { \ if ((d->openMode & WriteOnly) == 0) { \ - if (d->openMode == NotOpen) \ + if (d->openMode == NotOpen) { \ + qWarning("QIODevice::"#function": device not open"); \ return returnType; \ + } \ qWarning("QIODevice::"#function": ReadOnly device"); \ return returnType; \ } \ @@ -109,8 +111,10 @@ void debugBinaryString(const char *data, qint64 maxlen) #define CHECK_READABLE(function, returnType) \ do { \ if ((d->openMode & ReadOnly) == 0) { \ - if (d->openMode == NotOpen) \ + if (d->openMode == NotOpen) { \ + qWarning("QIODevice::"#function": device not open"); \ return returnType; \ + } \ qWarning("QIODevice::"#function": WriteOnly device"); \ return returnType; \ } \ -- cgit v1.2.3 From cd13fe44cd76e7aa821678fba58cb7d552aab2c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simo=20F=C3=A4lt?= Date: Mon, 7 Oct 2013 09:12:31 +0300 Subject: Skip tst_QGraphicsItem::paint() on Mac OS X 10.7 The test is randomly failing on CI when ran on 10.7. Task-number: QTBUG-31454 Change-Id: I79fce9a37616c6abaee960e338f8eea8fe6f31cf Reviewed-by: Jani Heikkinen Reviewed-by: Gunnar Sletta --- tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp index 2c03850181..b45ce88c83 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp @@ -5089,6 +5089,10 @@ public: void tst_QGraphicsItem::paint() { +#ifdef Q_OS_MACX + if (QSysInfo::MacintoshVersion == QSysInfo::MV_10_7) + QSKIP("QTBUG-31454 - Unstable auto-test"); +#endif QGraphicsScene scene; PaintTester paintTester; -- cgit v1.2.3 From 5c301f4121b4395b968ef3d6404986326ce70048 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Wed, 9 Oct 2013 13:34:53 +0200 Subject: Account for QPolygonF type when loading/saving the QVariant MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the QPolygonF type was added to QMetaType it did not bump up the values in load() and save() for QVariant. Task-number: QTBUG-33981 Change-Id: I7ad99cda70620c5449c15527c3daf920972d047f Reviewed-by: JÄ™drzej Nowacki Reviewed-by: Stephen Kelly --- src/corelib/kernel/qvariant.cpp | 7 +++- .../gui/kernel/qguivariant/test/data/qpolygonf.bin | Bin 0 -> 103 bytes .../gui/kernel/qguivariant/test/qguivariant.qrc | 5 +++ tests/auto/gui/kernel/qguivariant/test/test.pro | 1 + .../kernel/qguivariant/test/tst_qguivariant.cpp | 42 +++++++++++++++++++++ 5 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 tests/auto/gui/kernel/qguivariant/test/data/qpolygonf.bin create mode 100644 tests/auto/gui/kernel/qguivariant/test/qguivariant.qrc diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index 20e13a050f..5754af42ac 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -1892,6 +1892,7 @@ void QVariant::load(QDataStream &s) void QVariant::save(QDataStream &s) const { quint32 typeId = type(); + bool fakeUserType = false; if (s.version() < QDataStream::Qt_4_0) { int i; for (i = 0; i <= MapFromThreeCount - 1; ++i) { @@ -1916,12 +1917,16 @@ void QVariant::save(QDataStream &s) const } else if (typeId >= QMetaType::QKeySequence && typeId <= QMetaType::QQuaternion) { // and as a result these types received lower ids too typeId +=1; + } else if (typeId == QMetaType::QPolygonF) { + // This existed in Qt 4 only as a custom type + typeId = 127; + fakeUserType = true; } } s << typeId; if (s.version() >= QDataStream::Qt_4_2) s << qint8(d.is_null); - if (d.type >= QVariant::UserType) { + if (d.type >= QVariant::UserType || fakeUserType) { s << QMetaType::typeName(userType()); } diff --git a/tests/auto/gui/kernel/qguivariant/test/data/qpolygonf.bin b/tests/auto/gui/kernel/qguivariant/test/data/qpolygonf.bin new file mode 100644 index 0000000000..02e749b83f Binary files /dev/null and b/tests/auto/gui/kernel/qguivariant/test/data/qpolygonf.bin differ diff --git a/tests/auto/gui/kernel/qguivariant/test/qguivariant.qrc b/tests/auto/gui/kernel/qguivariant/test/qguivariant.qrc new file mode 100644 index 0000000000..576d9cda1c --- /dev/null +++ b/tests/auto/gui/kernel/qguivariant/test/qguivariant.qrc @@ -0,0 +1,5 @@ + + + data + + diff --git a/tests/auto/gui/kernel/qguivariant/test/test.pro b/tests/auto/gui/kernel/qguivariant/test/test.pro index d47cf7bf6f..e3b4a350ca 100644 --- a/tests/auto/gui/kernel/qguivariant/test/test.pro +++ b/tests/auto/gui/kernel/qguivariant/test/test.pro @@ -4,3 +4,4 @@ TARGET = tst_qguivariant SOURCES += tst_qguivariant.cpp INCLUDEPATH += $$PWD/../../../../other/qvariant_common QT += testlib +RESOURCES += qguivariant.qrc diff --git a/tests/auto/gui/kernel/qguivariant/test/tst_qguivariant.cpp b/tests/auto/gui/kernel/qguivariant/test/tst_qguivariant.cpp index 6fdf3dc843..8a68f40f3f 100644 --- a/tests/auto/gui/kernel/qguivariant/test/tst_qguivariant.cpp +++ b/tests/auto/gui/kernel/qguivariant/test/tst_qguivariant.cpp @@ -114,6 +114,7 @@ private slots: void writeToReadFromDataStream_data(); void writeToReadFromDataStream(); + void writeToReadFromOldDataStream(); void colorInteger(); void invalidQColor(); @@ -525,6 +526,7 @@ void tst_QGuiVariant::writeToReadFromDataStream_data() QTest::newRow( "pointarray_valid" ) << QVariant::fromValue( QPolygon( QRect( 10, 10, 20, 20 ) ) ) << false; QTest::newRow( "region_invalid" ) << QVariant::fromValue( QRegion() ) << true; QTest::newRow( "region_valid" ) << QVariant::fromValue( QRegion( 10, 10, 20, 20 ) ) << false; + QTest::newRow("polygonf_valid") << QVariant::fromValue(QPolygonF(QRectF(10, 10, 20, 20))) << false; } void tst_QGuiVariant::invalidQColor() @@ -609,6 +611,46 @@ void tst_QGuiVariant::writeToReadFromDataStream() } } +void tst_QGuiVariant::writeToReadFromOldDataStream() +{ + QPolygonF polyF(QRectF(10, 10, 50, 50)); + QVariant testVariant(polyF); + { + // Read into a variant and compare + QFile file(":/data/qpolygonf.bin"); + QVERIFY(file.open(QIODevice::ReadOnly)); + QDataStream dataFileStream(&file); + dataFileStream.setVersion(QDataStream::Qt_4_9); + QVariant readVariant; + dataFileStream >> readVariant; + QVERIFY(readVariant.type() == QMetaType::QPolygonF); + QCOMPARE(testVariant, readVariant); + file.close(); + } + { + QByteArray variantData; + { + QDataStream varDataStream(&variantData, QIODevice::WriteOnly); + varDataStream << testVariant; + } + // Read into a bytearray and compare + QFile file(":/data/qpolygonf.bin"); + QVERIFY(file.open(QIODevice::ReadOnly)); + QDataStream dataFileStream(&file); + dataFileStream.setVersion(QDataStream::Qt_4_9); + int dummy; + dataFileStream >> dummy; + QByteArray polyData49; + dataFileStream >> polyData49; + file.close(); + QByteArray polyData50; + QDataStream readVarData(variantData); + readVarData >> dummy; + readVarData >> polyData50; + QVERIFY(polyData49 == polyData50); + } +} + void tst_QGuiVariant::debugStream_data() { QTest::addColumn("variant"); -- cgit v1.2.3 From 37ca2224eca671200a2710f57f970d2993e62aa5 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Wed, 21 Aug 2013 10:08:50 +0200 Subject: QFileDialog: don't create widgets if the platform dialog will be used This is a performance and memory optimization which also fixes bugs that are related to creating widgets, file system models etc. despite using platform native dialogs. Similar to 785bc64f8e743ac269f15cbe7fecba93d3d507ac for QColorDialog. Task-number: QTBUG-33039 Change-Id: Ia1aa7ec1f43b47006b9ebd377aed15c958538a17 Reviewed-by: Friedemann Kleint --- .../platforms/windows/qwindowsdialoghelpers.cpp | 4 +- src/widgets/dialogs/qfiledialog.cpp | 266 +++++++++++++++------ src/widgets/dialogs/qfiledialog_p.h | 6 +- .../dialogs/qfiledialog/tst_qfiledialog.cpp | 17 ++ 4 files changed, 212 insertions(+), 81 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp index 0ecbf44194..0bf6838d9e 100644 --- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp +++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp @@ -578,8 +578,8 @@ bool QWindowsDialogHelperBase::show(Qt::WindowFlags, m_ownerWindow = 0; } if (QWindowsContext::verboseDialogs) - qDebug("%s modal=%d native=%p parent=%p" , - __FUNCTION__, modal, m_nativeDialog.data(), m_ownerWindow); + qDebug("%s modal=%d modal supported? %d native=%p parent=%p" , + __FUNCTION__, modal, supportsNonModalDialog(parent), m_nativeDialog.data(), m_ownerWindow); if (!modal && !supportsNonModalDialog(parent)) return false; // Was it changed in-between? if (!ensureNativeDialog()) diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index b688dfb0a4..383e3ab3f4 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -379,7 +379,6 @@ QFileDialog::QFileDialog(QWidget *parent, Qt::WindowFlags f) { Q_D(QFileDialog); d->init(); - d->lineEdit()->selectAll(); } /*! @@ -397,7 +396,6 @@ QFileDialog::QFileDialog(QWidget *parent, { Q_D(QFileDialog); d->init(directory, filter, caption); - d->lineEdit()->selectAll(); } /*! @@ -411,7 +409,6 @@ QFileDialog::QFileDialog(const QFileDialogArgs &args) setFileMode(args.mode); setOptions(args.options); selectFile(args.selection); - d->lineEdit()->selectAll(); } /*! @@ -443,7 +440,8 @@ QFileDialog::~QFileDialog() void QFileDialog::setSidebarUrls(const QList &urls) { Q_D(QFileDialog); - d->qFileDialogUi->sidebar->setUrls(urls); + if (!d->nativeDialogInUse) + d->qFileDialogUi->sidebar->setUrls(urls); } /*! @@ -453,7 +451,7 @@ void QFileDialog::setSidebarUrls(const QList &urls) QList QFileDialog::sidebarUrls() const { Q_D(const QFileDialog); - return d->qFileDialogUi->sidebar->urls(); + return (d->nativeDialogInUse ? QList() : d->qFileDialogUi->sidebar->urls()); } static const qint32 QFileDialogMagic = 0xbe; @@ -474,11 +472,19 @@ QByteArray QFileDialog::saveState() const stream << qint32(QFileDialogMagic); stream << qint32(version); - stream << d->qFileDialogUi->splitter->saveState(); - stream << d->qFileDialogUi->sidebar->urls(); + if (d->usingWidgets()) { + stream << d->qFileDialogUi->splitter->saveState(); + stream << d->qFileDialogUi->sidebar->urls(); + } else { + stream << QByteArray(); + stream << QList(); + } stream << history(); stream << *lastVisitedDir(); - stream << d->qFileDialogUi->treeView->header()->saveState(); + if (d->usingWidgets()) + stream << d->qFileDialogUi->treeView->header()->saveState(); + else + stream << QByteArray(); stream << qint32(viewMode()); return data; } @@ -520,6 +526,12 @@ bool QFileDialog::restoreState(const QByteArray &state) >> headerData >> viewMode; + setDirectory(lastVisitedDir()->isEmpty() ? currentDirectory : *lastVisitedDir()); + setViewMode(static_cast(viewMode)); + + if (!d->usingWidgets()) + return true; + if (!d->qFileDialogUi->splitter->restoreState(splitterState)) return false; QList list = d->qFileDialogUi->splitter->sizes(); @@ -533,7 +545,6 @@ bool QFileDialog::restoreState(const QByteArray &state) while (history.count() > 5) history.pop_front(); setHistory(history); - setDirectory(lastVisitedDir()->isEmpty() ? currentDirectory : *lastVisitedDir()); QHeaderView *headerView = d->qFileDialogUi->treeView->header(); if (!headerView->restoreState(headerData)) return false; @@ -548,7 +559,6 @@ bool QFileDialog::restoreState(const QByteArray &state) for (int i = 1; i < total; ++i) actions.at(i - 1)->setChecked(!headerView->isSectionHidden(i)); - setViewMode(ViewMode(viewMode)); return true; } @@ -595,15 +605,16 @@ void QFileDialogPrivate::initHelper(QPlatformDialogHelper *h) QObject::connect(h, SIGNAL(directoryEntered(QUrl)), d, SLOT(_q_nativeEnterDirectory(QUrl))); QObject::connect(h, SIGNAL(filterSelected(QString)), d, SIGNAL(filterSelected(QString))); static_cast(h)->setOptions(options); + nativeDialogInUse = true; } void QFileDialogPrivate::helperPrepareShow(QPlatformDialogHelper *) { Q_Q(QFileDialog); options->setWindowTitle(q->windowTitle()); - options->setViewMode(static_cast(q->viewMode())); options->setHistory(q->history()); - options->setSidebarUrls(qFileDialogUi->sidebar->urls()); + if (usingWidgets()) + options->setSidebarUrls(qFileDialogUi->sidebar->urls()); const QDir directory = q->directory(); options->setInitialDirectory(directory.exists() ? QUrl::fromLocalFile(directory.absolutePath()) : @@ -644,9 +655,17 @@ void QFileDialogPrivate::setLastVisitedDirectory(const QString &dir) *lastVisitedDir() = dir; } +void QFileDialogPrivate::updateLookInLabel() +{ + if (options->isLabelExplicitlySet(QFileDialogOptions::LookIn)) + setLabelTextControl(QFileDialog::LookIn, options->labelText(QFileDialogOptions::LookIn)); +} + void QFileDialogPrivate::updateFileNameLabel() { - if (!options->isLabelExplicitlySet(QFileDialogOptions::FileName)) { + if (options->isLabelExplicitlySet(QFileDialogOptions::FileName)) { + setLabelTextControl(QFileDialog::FileName, options->labelText(QFileDialogOptions::FileName)); + } else { switch (q_func()->fileMode()) { case QFileDialog::DirectoryOnly: case QFileDialog::Directory: @@ -659,6 +678,12 @@ void QFileDialogPrivate::updateFileNameLabel() } } +void QFileDialogPrivate::updateFileTypeLabel() +{ + if (options->isLabelExplicitlySet(QFileDialogOptions::FileType)) + setLabelTextControl(QFileDialog::FileType, options->labelText(QFileDialogOptions::FileType)); +} + void QFileDialogPrivate::updateOkButtonText(bool saveAsOnFolder) { Q_Q(QFileDialog); @@ -684,12 +709,20 @@ void QFileDialogPrivate::updateOkButtonText(bool saveAsOnFolder) } } +void QFileDialogPrivate::updateCancelButtonText() +{ + if (options->isLabelExplicitlySet(QFileDialogOptions::Reject)) + setLabelTextControl(QFileDialog::Reject, options->labelText(QFileDialogOptions::Reject)); +} + void QFileDialogPrivate::retranslateStrings() { Q_Q(QFileDialog); /* WIDGETS */ if (defaultFileTypes) q->setNameFilter(QFileDialog::tr("All Files (*)")); + if (nativeDialogInUse) + return; QList actions = qFileDialogUi->treeView->header()->actions(); QAbstractItemModel *abstractModel = model; @@ -708,7 +741,10 @@ void QFileDialogPrivate::retranslateStrings() showHiddenAction->setText(QFileDialog::tr("Show &hidden files")); newFolderAction->setText(QFileDialog::tr("&New Folder")); qFileDialogUi->retranslateUi(q); + updateLookInLabel(); updateFileNameLabel(); + updateFileTypeLabel(); + updateCancelButtonText(); } void QFileDialogPrivate::emitFilesSelected(const QStringList &files) @@ -734,6 +770,11 @@ bool QFileDialogPrivate::canBeNativeDialog() return (staticName == dynamicName); } +bool QFileDialogPrivate::usingWidgets() const +{ + return !nativeDialogInUse && qFileDialogUi; +} + /*! \since 4.5 Sets the given \a option to be enabled if \a on is true; otherwise, @@ -784,29 +825,36 @@ void QFileDialog::setOptions(Options options) return; d->options->setOptions(QFileDialogOptions::FileDialogOptions(int(options))); - if (changed & DontResolveSymlinks) - d->model->setResolveSymlinks(!(options & DontResolveSymlinks)); - if (changed & ReadOnly) { - bool ro = (options & ReadOnly); - d->model->setReadOnly(ro); - d->qFileDialogUi->newFolderButton->setEnabled(!ro); - d->renameAction->setEnabled(!ro); - d->deleteAction->setEnabled(!ro); + + if ((options & DontUseNativeDialog) && !d->usingWidgets()) + d->createWidgets(); + + if (d->usingWidgets()) { + if (changed & DontResolveSymlinks) + d->model->setResolveSymlinks(!(options & DontResolveSymlinks)); + if (changed & ReadOnly) { + bool ro = (options & ReadOnly); + d->model->setReadOnly(ro); + d->qFileDialogUi->newFolderButton->setEnabled(!ro); + d->renameAction->setEnabled(!ro); + d->deleteAction->setEnabled(!ro); + } + + if (changed & DontUseCustomDirectoryIcons) { + QFileIconProvider::Options providerOptions = iconProvider()->options(); + if (options & DontUseCustomDirectoryIcons) + providerOptions |= QFileIconProvider::DontUseCustomDirectoryIcons; + else + providerOptions &= ~QFileIconProvider::DontUseCustomDirectoryIcons; + iconProvider()->setOptions(providerOptions); + } } + if (changed & HideNameFilterDetails) setNameFilters(d->options->nameFilters()); if (changed & ShowDirsOnly) setFilter((options & ShowDirsOnly) ? filter() & ~QDir::Files : filter() | QDir::Files); - - if (changed & DontUseCustomDirectoryIcons) { - QFileIconProvider::Options providerOptions = iconProvider()->options(); - if (options & DontUseCustomDirectoryIcons) - providerOptions |= QFileIconProvider::DontUseCustomDirectoryIcons; - else - providerOptions &= ~QFileIconProvider::DontUseCustomDirectoryIcons; - iconProvider()->setOptions(providerOptions); - } } QFileDialog::Options QFileDialog::options() const @@ -858,21 +906,25 @@ void QFileDialog::setVisible(bool visible) // updates the state correctly, but skips showing the non-native version: setAttribute(Qt::WA_DontShowOnScreen); #ifndef QT_NO_FSCOMPLETER - //So the completer don't try to complete and therefore to show a popup - d->completer->setModel(0); + // So the completer doesn't try to complete and therefore show a popup + if (!d->nativeDialogInUse) + d->completer->setModel(0); #endif } else { + d->createWidgets(); setAttribute(Qt::WA_DontShowOnScreen, false); #ifndef QT_NO_FSCOMPLETER - if (d->proxyModel != 0) - d->completer->setModel(d->proxyModel); - else - d->completer->setModel(d->model); + if (!d->nativeDialogInUse) { + if (d->proxyModel != 0) + d->completer->setModel(d->proxyModel); + else + d->completer->setModel(d->model); + } #endif } } - if (!d->nativeDialogInUse) + if (d->usingWidgets()) d->qFileDialogUi->fileNameEdit->setFocus(); QDialog::setVisible(visible); @@ -914,24 +966,27 @@ void QFileDialog::setDirectory(const QString &directory) d->setLastVisitedDirectory(newDirectory); - if (d->nativeDialogInUse){ + d->options->setInitialDirectory(QUrl::fromLocalFile(directory)); + if (!d->usingWidgets()) { d->setDirectory_sys(QUrl::fromLocalFile(newDirectory)); return; } if (d->rootPath() == newDirectory) return; QModelIndex root = d->model->setRootPath(newDirectory); - d->qFileDialogUi->newFolderButton->setEnabled(d->model->flags(root) & Qt::ItemIsDropEnabled); - if (root != d->rootIndex()) { + if (!d->nativeDialogInUse) { + d->qFileDialogUi->newFolderButton->setEnabled(d->model->flags(root) & Qt::ItemIsDropEnabled); + if (root != d->rootIndex()) { #ifndef QT_NO_FSCOMPLETER - if (directory.endsWith(QLatin1Char('/'))) - d->completer->setCompletionPrefix(newDirectory); - else - d->completer->setCompletionPrefix(newDirectory + QLatin1Char('/')); + if (directory.endsWith(QLatin1Char('/'))) + d->completer->setCompletionPrefix(newDirectory); + else + d->completer->setCompletionPrefix(newDirectory + QLatin1Char('/')); #endif - d->setRootIndex(root); + d->setRootIndex(root); + } + d->qFileDialogUi->listView->selectionModel()->clear(); } - d->qFileDialogUi->listView->selectionModel()->clear(); } /*! @@ -989,8 +1044,11 @@ void QFileDialog::selectFile(const QString &filename) if (filename.isEmpty()) return; - if (d->nativeDialogInUse){ + if (!d->usingWidgets()) { d->selectFile_sys(QUrl::fromLocalFile(filename)); + QList i; + i << QUrl(filename); + d->options->setInitiallySelectedFiles(i); return; } @@ -1141,7 +1199,7 @@ QList QFileDialogPrivate::userSelectedFiles() const { QList files; - if (nativeDialogInUse) + if (!usingWidgets()) return addDefaultSuffixToUrls(selectedFiles_sys()); foreach (const QModelIndex &index, qFileDialogUi->listView->selectionModel()->selectedRows()) @@ -1339,6 +1397,9 @@ void QFileDialog::setNameFilters(const QStringList &filters) } d->options->setNameFilters(cleanedFilters); + if (!d->usingWidgets()) + return; + d->qFileDialogUi->fileTypeCombo->clear(); if (cleanedFilters.isEmpty()) return; @@ -1373,7 +1434,7 @@ QStringList QFileDialog::nameFilters() const void QFileDialog::selectNameFilter(const QString &filter) { Q_D(QFileDialog); - if (d->nativeDialogInUse) { + if (!d->usingWidgets()) { d->selectNameFilter_sys(filter); return; } @@ -1401,7 +1462,7 @@ void QFileDialog::selectNameFilter(const QString &filter) QString QFileDialog::selectedNameFilter() const { Q_D(const QFileDialog); - if (d->nativeDialogInUse) + if (!d->usingWidgets()) return d->selectedNameFilter_sys(); return d->qFileDialogUi->fileTypeCombo->currentText(); @@ -1417,7 +1478,9 @@ QString QFileDialog::selectedNameFilter() const QDir::Filters QFileDialog::filter() const { Q_D(const QFileDialog); - return d->model->filter(); + if (d->usingWidgets()) + return d->model->filter(); + return d->options->filter(); } /*! @@ -1432,13 +1495,13 @@ QDir::Filters QFileDialog::filter() const void QFileDialog::setFilter(QDir::Filters filters) { Q_D(QFileDialog); - d->model->setFilter(filters); d->options->setFilter(filters); - if (d->nativeDialogInUse){ + if (!d->usingWidgets()) { d->setFilter_sys(); return; } + d->model->setFilter(filters); d->showHiddenAction->setChecked((filters & QDir::Hidden)); } @@ -1523,6 +1586,9 @@ void QFileDialog::selectMimeTypeFilter(const QString &filter) void QFileDialog::setViewMode(QFileDialog::ViewMode mode) { Q_D(QFileDialog); + d->options->setViewMode(static_cast(mode)); + if (!d->usingWidgets()) + return; if (mode == Detail) d->_q_showDetailsView(); else @@ -1532,6 +1598,8 @@ void QFileDialog::setViewMode(QFileDialog::ViewMode mode) QFileDialog::ViewMode QFileDialog::viewMode() const { Q_D(const QFileDialog); + if (!d->usingWidgets()) + return QFileDialog::List; return (d->qFileDialogUi->stackedWidget->currentWidget() == d->qFileDialogUi->listView->parent() ? QFileDialog::List : QFileDialog::Detail); } @@ -1554,11 +1622,15 @@ void QFileDialog::setFileMode(QFileDialog::FileMode mode) { Q_D(QFileDialog); d->options->setFileMode(static_cast(mode)); - d->retranslateWindowTitle(); // keep ShowDirsOnly option in sync with fileMode (BTW, DirectoryOnly is obsolete) setOption(ShowDirsOnly, mode == DirectoryOnly); + if (!d->usingWidgets()) + return; + + d->retranslateWindowTitle(); + // set selection mode and behavior QAbstractItemView::SelectionMode selectionMode; if (mode == QFileDialog::ExistingFiles) @@ -1577,11 +1649,6 @@ void QFileDialog::setFileMode(QFileDialog::FileMode mode) } d->updateFileNameLabel(); d->updateOkButtonText(); - if (d->nativeDialogInUse){ - d->setFilter_sys(); - return; - } - d->qFileDialogUi->fileTypeCombo->setEnabled(!testOption(ShowDirsOnly)); d->_q_updateOkButton(); } @@ -1606,6 +1673,13 @@ void QFileDialog::setAcceptMode(QFileDialog::AcceptMode mode) { Q_D(QFileDialog); d->options->setAcceptMode(static_cast(mode)); + // clear WA_DontShowOnScreen so that d->canBeNativeDialog() doesn't return false incorrectly + setAttribute(Qt::WA_DontShowOnScreen, false); + if (!d->usingWidgets()) { + // we need to recreate the native dialog when changing the AcceptMode + d->deletePlatformHelper(); + return; + } QDialogButtonBox::StandardButton button = (mode == AcceptOpen ? QDialogButtonBox::Open : QDialogButtonBox::Save); d->qFileDialogUi->buttonBox->setStandardButtons(button | QDialogButtonBox::Cancel); d->qFileDialogUi->buttonBox->button(button)->setEnabled(false); @@ -1614,10 +1688,6 @@ void QFileDialog::setAcceptMode(QFileDialog::AcceptMode mode) d->qFileDialogUi->lookInCombo->setEditable(false); } d->retranslateWindowTitle(); - // we need to recreate the native dialog when changing the AcceptMode - d->deletePlatformHelper(); - // clear WA_DontShowOnScreen so that d->canBeNativeDialog() doesn't return false incorrectly - setAttribute(Qt::WA_DontShowOnScreen, false); } /* @@ -1778,7 +1848,8 @@ QString QFileDialog::defaultSuffix() const void QFileDialog::setHistory(const QStringList &paths) { Q_D(QFileDialog); - d->qFileDialogUi->lookInCombo->setHistory(paths); + if (d->usingWidgets()) + d->qFileDialogUi->lookInCombo->setHistory(paths); } void QFileDialogComboBox::setHistory(const QStringList &paths) @@ -1800,6 +1871,8 @@ void QFileDialogComboBox::setHistory(const QStringList &paths) QStringList QFileDialog::history() const { Q_D(const QFileDialog); + if (!d->usingWidgets()) + return QStringList(); QStringList currentHistory = d->qFileDialogUi->lookInCombo->history(); //On windows the popup display the "C:\", convert to nativeSeparators QString newHistory = QDir::toNativeSeparators(d->rootIndex().data(QFileSystemModel::FilePathRole).toString()); @@ -1826,6 +1899,8 @@ QStringList QFileDialog::history() const void QFileDialog::setItemDelegate(QAbstractItemDelegate *delegate) { Q_D(QFileDialog); + if (!d->usingWidgets()) + return; d->qFileDialogUi->listView->setItemDelegate(delegate); d->qFileDialogUi->treeView->setItemDelegate(delegate); } @@ -1836,6 +1911,8 @@ void QFileDialog::setItemDelegate(QAbstractItemDelegate *delegate) QAbstractItemDelegate *QFileDialog::itemDelegate() const { Q_D(const QFileDialog); + if (!d->usingWidgets()) + return 0; return d->qFileDialogUi->listView->itemDelegate(); } @@ -1845,6 +1922,8 @@ QAbstractItemDelegate *QFileDialog::itemDelegate() const void QFileDialog::setIconProvider(QFileIconProvider *provider) { Q_D(QFileDialog); + if (!d->usingWidgets()) + return; d->model->setIconProvider(provider); //It forces the refresh of all entries in the side bar, then we can get new icons d->qFileDialogUi->sidebar->setUrls(d->qFileDialogUi->sidebar->urls()); @@ -1861,6 +1940,8 @@ QFileIconProvider *QFileDialog::iconProvider() const void QFileDialogPrivate::setLabelTextControl(QFileDialog::DialogLabel label, const QString &text) { + if (!qFileDialogUi) + return; switch (label) { case QFileDialog::LookIn: qFileDialogUi->lookInLabel->setText(text); @@ -1903,8 +1984,10 @@ void QFileDialog::setLabelText(DialogLabel label, const QString &text) */ QString QFileDialog::labelText(DialogLabel label) const { - QPushButton *button; Q_D(const QFileDialog); + if (!d->usingWidgets()) + return d->options->labelText(static_cast(label)); + QPushButton *button; switch (label) { case LookIn: return d->qFileDialogUi->lookInLabel->text(); @@ -2518,7 +2601,7 @@ void QFileDialog::accept() QStringList files = selectedFiles(); if (files.isEmpty()) return; - if (d->nativeDialogInUse){ + if (!d->usingWidgets()) { d->emitFilesSelected(files); QDialog::accept(); return; @@ -2631,16 +2714,19 @@ void QFileDialogPrivate::init(const QString &directory, const QString &nameFilte q->setWindowTitle(caption); } - createWidgets(); - createMenuActions(); - retranslateStrings(); + q->setAcceptMode(QFileDialog::AcceptOpen); + nativeDialogInUse = (canBeNativeDialog() && platformFileDialogHelper() != 0); + if (!nativeDialogInUse) + createWidgets(); q->setFileMode(QFileDialog::AnyFile); + if (!nameFilter.isEmpty()) + q->setNameFilter(nameFilter); + q->setDirectory(workingDirectory(directory)); + q->selectFile(initialSelection(directory)); #ifndef QT_NO_SETTINGS QSettings settings(QSettings::UserScope, QLatin1String("QtProject")); settings.beginGroup(QLatin1String("Qt")); - if (!directory.isEmpty()) - setLastVisitedDirectory(workingDirectory(directory)); q->restoreState(settings.value(QLatin1String("filedialog")).toByteArray()); #endif @@ -2650,14 +2736,7 @@ void QFileDialogPrivate::init(const QString &directory, const QString &nameFilte qFileDialogUi->fileTypeLabel->setVisible(false); qFileDialogUi->sidebar->hide(); #endif - // Default case - if (!nameFilter.isEmpty()) - q->setNameFilter(nameFilter); - q->setAcceptMode(QFileDialog::AcceptOpen); - q->setDirectory(workingDirectory(directory)); - q->selectFile(initialSelection(directory)); - _q_updateOkButton(); q->resize(q->sizeHint()); } @@ -2668,6 +2747,8 @@ void QFileDialogPrivate::init(const QString &directory, const QString &nameFilte */ void QFileDialogPrivate::createWidgets() { + if (qFileDialogUi) + return; Q_Q(QFileDialog); model = new QFileSystemModel(q); options->setFilter(model->filter()); @@ -2676,6 +2757,8 @@ void QFileDialogPrivate::createWidgets() model->setNameFilterDisables(helper->defaultNameFilterDisables()); else model->setNameFilterDisables(false); + if (nativeDialogInUse) + deletePlatformHelper(); model->d_func()->disableRecursiveSort = true; QFileDialog::connect(model, SIGNAL(fileRenamed(QString,QString,QString)), q, SLOT(_q_fileRenamed(QString,QString,QString))); QFileDialog::connect(model, SIGNAL(rootPathChanged(QString)), @@ -2789,6 +2872,31 @@ void QFileDialogPrivate::createWidgets() qFileDialogUi->splitter->setStretchFactor(qFileDialogUi->splitter->indexOf(qFileDialogUi->splitter->widget(1)), QSizePolicy::Expanding); createToolButtons(); + createMenuActions(); + + // Initial widget states from options + q->setFileMode(static_cast(options->fileMode())); + q->setAcceptMode(static_cast(options->acceptMode())); + q->setViewMode(static_cast(options->viewMode())); + q->setOptions(static_cast(static_cast(options->options()))); + if (!options->sidebarUrls().isEmpty()) + q->setSidebarUrls(options->sidebarUrls()); + q->setDirectoryUrl(options->initialDirectory()); + if (!options->mimeTypeFilters().isEmpty()) + q->setMimeTypeFilters(options->mimeTypeFilters()); + else if (!options->nameFilters().isEmpty()) + q->setNameFilters(options->nameFilters()); + q->selectNameFilter(options->initiallySelectedNameFilter()); + q->setDefaultSuffix(options->defaultSuffix()); + q->setHistory(options->history()); + if (options->initiallySelectedFiles().count() == 1) + q->selectFile(options->initiallySelectedFiles().first().fileName()); + foreach (QUrl url, options->initiallySelectedFiles()) + q->selectUrl(url); + lineEdit()->selectAll(); + _q_updateOkButton(); + retranslateStrings(); + q->resize(q->sizeHint()); } void QFileDialogPrivate::_q_showHeader(QAction *action) @@ -2814,6 +2922,8 @@ void QFileDialogPrivate::_q_showHeader(QAction *action) void QFileDialog::setProxyModel(QAbstractProxyModel *proxyModel) { Q_D(QFileDialog); + if (!d->usingWidgets()) + return; if ((!proxyModel && !d->proxyModel) || (proxyModel == d->proxyModel)) return; diff --git a/src/widgets/dialogs/qfiledialog_p.h b/src/widgets/dialogs/qfiledialog_p.h index e5a558bb91..36336bdbf6 100644 --- a/src/widgets/dialogs/qfiledialog_p.h +++ b/src/widgets/dialogs/qfiledialog_p.h @@ -135,8 +135,11 @@ public: QList addDefaultSuffixToUrls(const QList &urlsToFix) const; bool removeDirectory(const QString &path); void setLabelTextControl(QFileDialog::DialogLabel label, const QString &text); + inline void updateLookInLabel(); inline void updateFileNameLabel(); + inline void updateFileTypeLabel(); void updateOkButtonText(bool saveAsOnFolder = false); + void updateCancelButtonText(); inline QModelIndex mapToSource(const QModelIndex &index) const; inline QModelIndex mapFromSource(const QModelIndex &index) const; @@ -249,6 +252,7 @@ public: // dialog. Returning false means that a non-native dialog must be // used instead. bool canBeNativeDialog(); + inline bool usingWidgets() const; void setDirectory_sys(const QUrl &directory); QUrl directory_sys() const; @@ -347,7 +351,7 @@ inline QModelIndex QFileDialogPrivate::mapFromSource(const QModelIndex &index) c } inline QString QFileDialogPrivate::rootPath() const { - return model->rootPath(); + return (model ? model->rootPath() : QStringLiteral("/")); } inline void QFileDialogPrivate::setDirectory_sys(const QUrl &directory) diff --git a/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp b/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp index 81b69f6b89..8bad4bb176 100644 --- a/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp +++ b/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp @@ -66,6 +66,8 @@ #include #include #endif +#include +#include #include #include @@ -145,6 +147,7 @@ private slots: void clearLineEdit(); void enableChooseButton(); void hooks(); + void widgetlessNativeDialog(); #ifdef Q_OS_UNIX #ifdef QT_BUILD_INTERNAL void tildeExpansion_data(); @@ -1396,6 +1399,20 @@ void tst_QFiledialog::hooks() QCOMPARE(QFileDialog::getSaveFileUrl(), QUrl("http://saveUrl")); } +void tst_QFiledialog::widgetlessNativeDialog() +{ + if (!QGuiApplicationPrivate::platformTheme()->usePlatformNativeDialog(QPlatformTheme::FileDialog)) + QSKIP("This platform always uses widgets to realize its QFileDialog, instead of the native file dialog."); + QFileDialog fd; + fd.setWindowModality(Qt::ApplicationModal); + fd.show(); + QTRY_VERIFY(fd.isVisible()); + QFileSystemModel *model = fd.findChild("qt_filesystem_model"); + QVERIFY(!model); + QPushButton *button = fd.findChild(); + QVERIFY(!button); +} + #ifdef Q_OS_UNIX #ifdef QT_BUILD_INTERNAL void tst_QFiledialog::tildeExpansion_data() -- cgit v1.2.3 From cfb717d654b92dcfde94cddc7039abeafe67f289 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorbj=C3=B8rn=20Martsum?= Date: Thu, 26 Sep 2013 15:48:41 +0200 Subject: QList - fix a few doc issues Though some of it was mensioned in the introduction to the class, we are not in O(1) if we modify a shared container. Change-Id: If63b4cb4bdfc98d6b1333bae307e5650341e5484 Reviewed-by: Sze Howe Koh Reviewed-by: Thiago Macieira --- src/corelib/tools/qlist.cpp | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/corelib/tools/qlist.cpp b/src/corelib/tools/qlist.cpp index 5bced19404..d8ccf2cc43 100644 --- a/src/corelib/tools/qlist.cpp +++ b/src/corelib/tools/qlist.cpp @@ -647,7 +647,10 @@ void **QListData::erase(void **xi) \a i must be a valid index position in the list (i.e., 0 <= \a i < size()). - This function is very fast (\l{constant time}). + If this function is called on a list that is currently being shared, it + will trigger a copy of all elements. Otherwise, this function runs in + \l{constant time}. If you do not want to modify the list you should use + QList::at(). \sa at(), value() */ @@ -656,7 +659,7 @@ void **QListData::erase(void **xi) \overload - Same as at(). + Same as at(). This function runs in \l{constant time}. */ /*! \fn QList::reserve(int alloc) @@ -681,10 +684,10 @@ void **QListData::erase(void **xi) This is the same as list.insert(size(), \a value). - This operation is typically very fast (\l{constant time}), - because QList preallocates extra space on both sides of its - internal buffer to allow for fast growth at both ends of the - list. + If this list is not shared, this operation is typically + very fast (amortized \l{constant time}), because QList + preallocates extra space on both sides of its internal + buffer to allow for fast growth at both ends of the list. \sa operator<<(), prepend(), insert() */ @@ -709,8 +712,9 @@ void **QListData::erase(void **xi) This is the same as list.insert(0, \a value). - This operation is usually very fast (\l{constant time}), because - QList preallocates extra space on both sides of its internal + If this list is not shared, this operation is typically + very fast (amortized \l{constant time}), because QList + preallocates extra space on both sides of its internal buffer to allow for fast growth at both ends of the list. \sa append(), insert() @@ -802,7 +806,7 @@ void **QListData::erase(void **xi) same as takeAt(0). This function assumes the list is not empty. To avoid failure, call isEmpty() before calling this function. - This operation takes \l{constant time}. + If this list is not shared, this operation takes \l{constant time}. If you don't use the return value, removeFirst() is more efficient. @@ -817,7 +821,7 @@ void **QListData::erase(void **xi) not empty. To avoid failure, call isEmpty() before calling this function. - This operation takes \l{constant time}. + If this list is not shared, this operation takes \l{constant time}. If you don't use the return value, removeLast() is more efficient. -- cgit v1.2.3 From 499957eb8b1c5150823f05f40f32b04ba13b1640 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorbj=C3=B8rn=20Martsum?= Date: Tue, 24 Sep 2013 16:42:22 +0200 Subject: Improve implicit shared documentation a bit Task-number: QTBUG-27061 Change-Id: I66e000a9f59fda3654066013e6e78c3ba6fd27fe Reviewed-by: Mitch Curtis Reviewed-by: Thiago Macieira --- .../doc/snippets/code/doc_src_containers.cpp | 30 ++++++++++++++++++++++ src/corelib/doc/src/containers.qdoc | 14 +++++++--- src/corelib/doc/src/implicit-sharing.qdoc | 20 +++++++++------ src/corelib/tools/qhash.cpp | 10 ++++++++ src/corelib/tools/qlinkedlist.cpp | 14 +++++++--- src/corelib/tools/qlist.cpp | 10 ++++++++ src/corelib/tools/qmap.cpp | 10 ++++++++ src/corelib/tools/qset.qdoc | 14 +++++++--- src/corelib/tools/qvector.cpp | 10 ++++++++ 9 files changed, 114 insertions(+), 18 deletions(-) diff --git a/src/corelib/doc/snippets/code/doc_src_containers.cpp b/src/corelib/doc/snippets/code/doc_src_containers.cpp index 350b2a91f2..6e59a8a548 100644 --- a/src/corelib/doc/snippets/code/doc_src_containers.cpp +++ b/src/corelib/doc/snippets/code/doc_src_containers.cpp @@ -273,3 +273,33 @@ QString onlyLetters(const QString &in) return out; } //! [23] + +//! [24] +QVector a, b; +a.resize(100000); // make a big vector filled with 0. + +QVector::iterator i = a.begin(); +// WRONG way of using the iterator i: +b = a; +/* + Now we should be careful with iterator i since it will point to shared data + If we do *i = 4 then we would change the shared instance (both vectors) + The behavior differs from STL containers. Avoid doing such things in Qt. +*/ + +a[0] = 5; +/* + Container a is now detached from the shared data, + and even though i was an iterator from the container a, it now works as an iterator in b. + Here the situation is that (*i) == 0. +*/ + +b.clear(); // Now the iterator i is completely invalid. + +int j = *i; // Undefined behavior! +/* + The data from b (which i pointed to) is gone. + This would be well-defined with STL containers (and (*i) == 5), + but with QVector this is likely to crash. +*/ +//! [24] diff --git a/src/corelib/doc/src/containers.qdoc b/src/corelib/doc/src/containers.qdoc index ff2df9c020..fa26409d83 100644 --- a/src/corelib/doc/src/containers.qdoc +++ b/src/corelib/doc/src/containers.qdoc @@ -533,10 +533,18 @@ This problem doesn't occur with functions that return a const or non-const reference to a container. + \section3 Implicit sharing iterator problem + \l{Implicit sharing} has another consequence on STL-style - iterators: You must not take a copy of a container while - non-const iterators are active on that container. Java-style - iterators don't suffer from that limitation. + iterators: you should avoid copying a container while + iterators are active on that container. The iterators + point to an internal structure, and if you copy a container + you should be very careful with your iterators. E.g: + + \snippet code/doc_src_containers.cpp 24 + + The above example only shows a problem with QVector, but + the problem exists for all the implicitly shared Qt containers. \keyword foreach \section1 The foreach Keyword diff --git a/src/corelib/doc/src/implicit-sharing.qdoc b/src/corelib/doc/src/implicit-sharing.qdoc index 814f8140f3..1185fe8348 100644 --- a/src/corelib/doc/src/implicit-sharing.qdoc +++ b/src/corelib/doc/src/implicit-sharing.qdoc @@ -89,9 +89,12 @@ of data. Objects can easily be assigned, sent as function arguments, and returned from functions. - Implicit sharing takes place behind the scenes; the programmer - does not need to worry about it. Even in multithreaded - applications, implicit sharing takes place, as explained in + Implicit sharing mostly takes place behind the scenes; + the programmer rarely needs to worry about it. However, Qt's + container iterators have different behavior than those from + the STL. Read \l{Implicit sharing iterator problem}. + + In multithreaded applications, implicit sharing takes place, as explained in \l{Thread-Support in Qt Modules#Threads and Implicitly Shared Classes} {Threads and Implicitly Shared Classes}. @@ -105,9 +108,10 @@ greater than one. (This is often called \e {copy-on-write} or \e {value semantics}.) - An implicitly shared class has total control of its internal data. In + An implicitly shared class has control of its internal data. In any member functions that modify its data, it automatically detaches - before modifying the data. + before modifying the data. Notice, however, the special case with + container iterators; see \l{Implicit sharing iterator problem}. The QPen class, which uses implicit sharing, detaches from the shared data in all member functions that change the internal data. @@ -133,9 +137,9 @@ In this example, \c p1 and \c p2 share data until QPainter::begin() is called for \c p2, because painting a pixmap will modify it. - \warning Do not copy an implicitly shared container (QMap, - QVector, etc.) while you are iterating over it using an non-const - \l{STL-style iterators}{STL-style iterator}. + \warning Be careful with copying an implicitly shared container + (QMap, QVector, etc.) while you use + \l{STL-style iterators}{STL-style iterator}. See \l{Implicit sharing iterator problem}. \keyword implicitly shared classes \annotatedlist shared diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp index 7f6feaf8a0..f14fac00b8 100644 --- a/src/corelib/tools/qhash.cpp +++ b/src/corelib/tools/qhash.cpp @@ -1594,6 +1594,11 @@ void QHashData::checkSanity() need to keep iterators over a long period of time, we recommend that you use QMap rather than QHash. + \warning Iterators on implicitly shared containers do not work + exactly like STL-iterators. You should avoid copying a container + while iterators are active on that container. For more information, + read \l{Implicit sharing iterator problem}. + \sa QHash::const_iterator, QMutableHashIterator */ @@ -1791,6 +1796,11 @@ void QHashData::checkSanity() internal data structure. If you need to keep iterators over a long period of time, we recommend that you use QMap rather than QHash. + \warning Iterators on implicitly shared containers do not work + exactly like STL-iterators. You should avoid copying a container + while iterators are active on that container. For more information, + read \l{Implicit sharing iterator problem}. + \sa QHash::iterator, QHashIterator */ diff --git a/src/corelib/tools/qlinkedlist.cpp b/src/corelib/tools/qlinkedlist.cpp index 28319f3fda..e967163b8b 100644 --- a/src/corelib/tools/qlinkedlist.cpp +++ b/src/corelib/tools/qlinkedlist.cpp @@ -691,9 +691,12 @@ const QLinkedListData QLinkedListData::shared_null = { Multiple iterators can be used on the same list. If you add items to the list, existing iterators will remain valid. If you remove items from the list, iterators that point to the removed items - will become dangling iterators. However, because of how \l{implicit - sharing} works, you must not take a copy of a container while - iterators are active on that container. + will become dangling iterators. + + \warning Iterators on implicitly shared containers do not work + exactly like STL-iterators. You should avoid copying a container + while iterators are active on that container. For more information, + read \l{Implicit sharing iterator problem}. \sa QLinkedList::const_iterator, QMutableLinkedListIterator */ @@ -910,6 +913,11 @@ const QLinkedListData QLinkedListData::shared_null = { items from the list, iterators that point to the removed items will become dangling iterators. + \warning Iterators on implicitly shared containers do not work + exactly like STL-iterators. You should avoid copying a container + while iterators are active on that container. For more information, + read \l{Implicit sharing iterator problem}. + \sa QLinkedList::iterator, QLinkedListIterator */ diff --git a/src/corelib/tools/qlist.cpp b/src/corelib/tools/qlist.cpp index d8ccf2cc43..0811c3793e 100644 --- a/src/corelib/tools/qlist.cpp +++ b/src/corelib/tools/qlist.cpp @@ -1292,6 +1292,11 @@ void **QListData::erase(void **xi) iterators over a long period of time, we recommend that you use QLinkedList rather than QList. + \warning Iterators on implicitly shared containers do not work + exactly like STL-iterators. You should avoid copying a container + while iterators are active on that container. For more information, + read \l{Implicit sharing iterator problem}. + \sa QList::const_iterator, QMutableListIterator */ @@ -1542,6 +1547,11 @@ void **QListData::erase(void **xi) iterators over a long period of time, we recommend that you use QLinkedList rather than QList. + \warning Iterators on implicitly shared containers do not work + exactly like STL-iterators. You should avoid copying a container + while iterators are active on that container. For more information, + read \l{Implicit sharing iterator problem}. + \sa QList::iterator, QListIterator */ diff --git a/src/corelib/tools/qmap.cpp b/src/corelib/tools/qmap.cpp index ab9b1d23ab..4da9669a39 100644 --- a/src/corelib/tools/qmap.cpp +++ b/src/corelib/tools/qmap.cpp @@ -1215,6 +1215,11 @@ void QMapDataBase::freeData(QMapDataBase *d) items from the map, iterators that point to the removed items will become dangling iterators. + \warning Iterators on implicitly shared containers do not work + exactly like STL-iterators. You should avoid copying a container + while iterators are active on that container. For more information, + read \l{Implicit sharing iterator problem}. + \sa QMap::const_iterator, QMutableMapIterator */ @@ -1433,6 +1438,11 @@ void QMapDataBase::freeData(QMapDataBase *d) items from the map, iterators that point to the removed items will become dangling iterators. + \warning Iterators on implicitly shared containers do not work + exactly like STL-iterators. You should avoid copying a container + while iterators are active on that container. For more information, + read \l{Implicit sharing iterator problem}. + \sa QMap::iterator, QMapIterator */ diff --git a/src/corelib/tools/qset.qdoc b/src/corelib/tools/qset.qdoc index a0bc206014..e66a59a09c 100644 --- a/src/corelib/tools/qset.qdoc +++ b/src/corelib/tools/qset.qdoc @@ -643,8 +643,12 @@ \snippet code/doc_src_qset.cpp 10 - Multiple iterators can be used on the same set. However, you may - not attempt to modify the container while iterating on it. + Multiple iterators can be used on the same set. + + \warning Iterators on implicitly shared containers do not work + exactly like STL-iterators. You should avoid copying a container + while iterators are active on that container. For more information, + read \l{Implicit sharing iterator problem}. \sa QSet::const_iterator, QMutableSetIterator */ @@ -682,8 +686,10 @@ \snippet code/doc_src_qset.cpp 12 - Multiple iterators can be used on the same set. However, you may - not attempt to modify the container while iterating on it. + \warning Iterators on implicitly shared containers do not work + exactly like STL-iterators. You should avoid copying a container + while iterators are active on that container. For more information, + read \l{Implicit sharing iterator problem}. \sa QSet::iterator, QSetIterator */ diff --git a/src/corelib/tools/qvector.cpp b/src/corelib/tools/qvector.cpp index 11990d30b2..b9281c6915 100644 --- a/src/corelib/tools/qvector.cpp +++ b/src/corelib/tools/qvector.cpp @@ -957,6 +957,11 @@ iterators}. The STL-style non-const iterator is simply a typedef for "T *" (pointer to T). + \warning Iterators on implicitly shared containers do not work + exactly like STL-iterators. You should avoid copying a container + while iterators are active on that container. For more information, + read \l{Implicit sharing iterator problem}. + \sa QVector::begin(), QVector::end(), QVector::const_iterator, QMutableVectorIterator */ @@ -969,6 +974,11 @@ iterators}. The STL-style const iterator is simply a typedef for "const T *" (pointer to const T). + \warning Iterators on implicitly shared containers do not work + exactly like STL-iterators. You should avoid copying a container + while iterators are active on that container. For more information, + read \l{Implicit sharing iterator problem}. + \sa QVector::constBegin(), QVector::constEnd(), QVector::iterator, QVectorIterator */ -- cgit v1.2.3 From 5482881b8a7103eb12ec9662dd2198755c6e3c18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorbj=C3=B8rn=20Martsum?= Date: Tue, 24 Sep 2013 06:37:41 +0200 Subject: QMap - improve docs a bit (mainly by adding more time complexities) Change-Id: I8a361ef09c338bbba228fd774b2bfd938869adc5 Reviewed-by: Olivier Goffart Reviewed-by: Thiago Macieira --- src/corelib/tools/qmap.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/corelib/tools/qmap.cpp b/src/corelib/tools/qmap.cpp index 4da9669a39..9aebbb7b3c 100644 --- a/src/corelib/tools/qmap.cpp +++ b/src/corelib/tools/qmap.cpp @@ -395,7 +395,7 @@ void QMapDataBase::freeData(QMapDataBase *d) differences are: \list - \li QHash provides faster lookups than QMap. (See \l{Algorithmic + \li QHash provides average faster lookups than QMap. (See \l{Algorithmic Complexity} for details.) \li When iterating over a QHash, the items are arbitrarily ordered. With QMap, the items are always sorted by key. @@ -901,6 +901,8 @@ void QMapDataBase::freeData(QMapDataBase *d) Returns a reference to the smallest key in the map. This function assumes that the map is not empty. + This executes in \l{constant time}. + \sa lastKey(), first(), isEmpty() */ @@ -909,6 +911,8 @@ void QMapDataBase::freeData(QMapDataBase *d) Returns a reference to the largest key in the map. This function assumes that the map is not empty. + This executes in \l{logarithmic time}. + \sa firstKey(), last(), isEmpty() */ @@ -917,6 +921,8 @@ void QMapDataBase::freeData(QMapDataBase *d) Returns a reference to the first value in the map, that is the value mapped to the smallest key. This function assumes that the map is not empty. + When unshared (or const version is called), this executes in \l{constant time}. + \sa last(), firstKey(), isEmpty() */ @@ -930,6 +936,8 @@ void QMapDataBase::freeData(QMapDataBase *d) Returns a reference to the last value in the map, that is the value mapped to the largest key. This function assumes that the map is not empty. + When unshared (or const version is called), this executes in \l{logarithmic time}. + \sa first(), lastKey(), isEmpty() */ @@ -1057,8 +1065,11 @@ void QMapDataBase::freeData(QMapDataBase *d) If there are multiple items with the key \a key, then exactly one of them is replaced with \a value. + If the hint is correct and the map is unshared, the insert executes in amortized \l{constant time}. + When creating a map from sorted data inserting the largest key first with constBegin() - is faster than inserting in sorted order with constEnd() + is faster than inserting in sorted order with constEnd(), since constEnd() - 1 (which is needed + to check if the hint is valid) needs \l{logarithmic time}. \b {Note:} Be careful with the hint. Providing an iterator from an older shared instance might crash but there is also a risk that it will silently corrupt both the map and the \a pos map. -- cgit v1.2.3 From 407ac121b98f3f8cbcddda58f1f75caf364fce42 Mon Sep 17 00:00:00 2001 From: Mark Brand Date: Wed, 9 Oct 2013 13:28:59 +0200 Subject: configure: gif driver is always bundled code, so say so Change-Id: Ibd228cc63b1f4feb6364e052daa239be14253ec0 Reviewed-by: Oswald Buddenhagen Reviewed-by: Thiago Macieira --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index 388899e5e4..4e0d6f1e07 100755 --- a/configure +++ b/configure @@ -6890,7 +6890,7 @@ report_support " FreeType ..............." "$CFG_FREETYPE" report_support " Iconv .................." "$CFG_ICONV" report_support " ICU ...................." "$CFG_ICU" report_support " Image formats:" -report_support_plugin " GIF .................." "$CFG_GIF" system QtGui +report_support_plugin " GIF .................." "$CFG_GIF" qt QtGui report_support_plugin " JPEG ................." "$CFG_JPEG" "$CFG_LIBJPEG" QtGui report_support_plugin " PNG .................." "$CFG_PNG" "$CFG_LIBPNG" QtGui report_support " Glib ..................." "$CFG_GLIB" -- cgit v1.2.3 From b8da27bc909ccef51269a59233d2b943e9acb220 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Mon, 22 Jul 2013 19:24:49 +0200 Subject: Update keycode mappings of multimedia keys Updates keycode mappings for evdev, directfb and android. Change-Id: I6789f13dbb662da4261a3c947757644e12306dd9 Reviewed-by: BogDan Vatra --- src/corelib/global/qnamespace.h | 10 ++--- .../evdevkeyboard/qevdevkeyboard_defaultmap_p.h | 28 +++++++++++- .../platforms/android/src/androidjniinput.cpp | 50 +++++++++++++++++++--- .../platforms/directfb/qdirectfbconvenience.cpp | 4 ++ 4 files changed, 80 insertions(+), 12 deletions(-) diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index 420721cb54..e2c6039989 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -907,7 +907,7 @@ public: Key_BrightnessAdjust = 0x010000c2, Key_Finance = 0x010000c3, Key_Community = 0x010000c4, - Key_AudioRewind = 0x010000c5, + Key_AudioRewind = 0x010000c5, // Media rewind Key_BackForward = 0x010000c6, Key_ApplicationLeft = 0x010000c7, Key_ApplicationRight = 0x010000c8, @@ -919,7 +919,7 @@ public: Key_Close = 0x010000ce, Key_Copy = 0x010000cf, Key_Cut = 0x010000d0, - Key_Display = 0x010000d1, + Key_Display = 0x010000d1, // Output switch key Key_DOS = 0x010000d2, Key_Documents = 0x010000d3, Key_Excel = 0x010000d4, @@ -968,9 +968,9 @@ public: Key_Bluetooth = 0x010000ff, Key_WLAN = 0x01000100, Key_UWB = 0x01000101, - Key_AudioForward = 0x01000102, - Key_AudioRepeat = 0x01000103, - Key_AudioRandomPlay = 0x01000104, + Key_AudioForward = 0x01000102, // Media fast-forward + Key_AudioRepeat = 0x01000103, // Toggle repeat mode + Key_AudioRandomPlay = 0x01000104, // Toggle shuffle mode Key_Subtitle = 0x01000105, Key_AudioCycleTrack = 0x01000106, Key_Time = 0x01000107, diff --git a/src/platformsupport/input/evdevkeyboard/qevdevkeyboard_defaultmap_p.h b/src/platformsupport/input/evdevkeyboard/qevdevkeyboard_defaultmap_p.h index 22d1622516..225b3d41ef 100644 --- a/src/platformsupport/input/evdevkeyboard/qevdevkeyboard_defaultmap_p.h +++ b/src/platformsupport/input/evdevkeyboard/qevdevkeyboard_defaultmap_p.h @@ -42,6 +42,9 @@ #ifndef QEVDEVKEYBOARDHANDLER_DEFAULTMAP_P_H #define QEVDEVKEYBOARDHANDLER_DEFAULTMAP_P_H +#include "qnamespace.h" +#include "linux/input.h" + // no QT_BEGIN_NAMESPACE, since we include it internally... const QEvdevKeyboardMap::Mapping QEvdevKeyboardHandler::s_keymap_default[] = { @@ -631,7 +634,30 @@ const QEvdevKeyboardMap::Mapping QEvdevKeyboardHandler::s_keymap_default[] = { { 111, 0xffff, 0x01000007, 0x00, 0x00, 0x0000 }, { 111, 0xffff, 0x01000000, 0x06, 0x08, 0x0200 }, { 111, 0xffff, 0x01000000, 0x0c, 0x08, 0x0200 }, - { 119, 0xffff, 0x01000008, 0x00, 0x00, 0x0000 }, + + // 113 -> 248 + { KEY_MUTE, 0xffff, Qt::Key_VolumeMute, 0x00, 0x00, 0x0000 }, + { KEY_VOLUMEDOWN, 0xffff, Qt::Key_VolumeDown, 0x00, 0x00, 0x0000 }, + { KEY_VOLUMEUP, 0xffff, Qt::Key_VolumeUp, 0x00, 0x00, 0x0000 }, + { KEY_PAUSE, 0xffff, Qt::Key_Pause, 0x00, 0x00, 0x0000 }, + { KEY_STOP, 0xffff, Qt::Key_Stop, 0x00, 0x00, 0x0000 }, + { KEY_RECORD, 0xffff, Qt::Key_MediaRecord, 0x00, 0x00, 0x0000 }, + { KEY_REWIND, 0xffff, Qt::Key_AudioRewind, 0x00, 0x00, 0x0000 }, + { KEY_PLAYPAUSE, 0xffff, Qt::Key_MediaTogglePlayPause, 0x00, 0x00, 0x0000 }, + { KEY_PLAY, 0xffff, Qt::Key_MediaPlay, 0x00, 0x00, 0x0000 }, + { KEY_FASTFORWARD, 0xffff, Qt::Key_AudioForward, 0x00, 0x00, 0x0000 }, + { KEY_CANCEL, 0xffff, Qt::Key_Cancel, 0x00, 0x00, 0x0000 }, + { 248, 0xffff, Qt::Key_MicMute, 0x00, 0x00, 0x0000 }, + // 0x160 -> + { KEY_SELECT, 0xffff, Qt::Key_Select, 0x00, 0x00, 0x0000 }, + { KEY_CLEAR, 0xffff, Qt::Key_Clear, 0x00, 0x00, 0x0000 }, + { KEY_CALENDAR, 0xffff, Qt::Key_Calendar, 0x00, 0x00, 0x0000 }, + { KEY_RED, 0xffff, Qt::Key_Red, 0x00, 0x00, 0x0000 }, + { KEY_GREEN, 0xffff, Qt::Key_Green, 0x00, 0x00, 0x0000 }, + { KEY_YELLOW, 0xffff, Qt::Key_Yellow, 0x00, 0x00, 0x0000 }, + { KEY_BLUE, 0xffff, Qt::Key_Blue, 0x00, 0x00, 0x0000 }, + { KEY_CHANNELUP, 0xffff, Qt::Key_ChannelUp, 0x00, 0x00, 0x0000 }, + { KEY_CHANNELDOWN, 0xffff, Qt::Key_ChannelDown, 0x00, 0x00, 0x0000 }, }; const QEvdevKeyboardMap::Composing QEvdevKeyboardHandler::s_keycompose_default[] = { diff --git a/src/plugins/platforms/android/src/androidjniinput.cpp b/src/plugins/platforms/android/src/androidjniinput.cpp index 4a2d87d6a4..bd40f736e0 100644 --- a/src/plugins/platforms/android/src/androidjniinput.cpp +++ b/src/plugins/platforms/android/src/androidjniinput.cpp @@ -271,8 +271,8 @@ namespace QtAndroidInput case 0x00000005: return Qt::Key_Call; - case 0x0000001b: - return Qt::Key_WebCam; + case 0x0000001b: // KEYCODE_CAMERA + return Qt::Key_Camera; case 0x0000001c: return Qt::Key_Clear; @@ -280,7 +280,7 @@ namespace QtAndroidInput case 0x00000037: return Qt::Key_Comma; - case 0x00000043: + case 0x00000043: // KEYCODE_DEL return Qt::Key_Backspace; case 0x00000017: // KEYCODE_DPAD_CENTER @@ -398,6 +398,27 @@ namespace QtAndroidInput case 0x00000018: return Qt::Key_VolumeUp; + case 0x00000011: // KEYCODE_STAR + return Qt::Key_Asterisk; + + case 0x00000012: // KEYCODE_POUND + return Qt::Key_NumberSign; + + case 0x00000050: // KEYCODE_FOCUS + return Qt::Key_CameraFocus; + + case 0x00000070: // KEYCODE_FORWARD_DEL + return Qt::Key_Delete; + + case 0x00000080: // KEYCODE_MEDIA_CLOSE + return Qt::Key_Close; + + case 0x00000081: // KEYCODE_MEDIA_EJECT + return Qt::Key_Eject; + + case 0x00000082: // KEYCODE_MEDIA_RECORD + return Qt::Key_MediaRecord; + case 0x000000b7: // KEYCODE_PROG_RED return Qt::Key_Red; @@ -416,13 +437,30 @@ namespace QtAndroidInput case 0x000000a7: // KEYCODE_CHANNEL_DOWN return Qt::Key_ChannelDown; + case 0x000000a8: // KEYCODE_ZOOM_IN + return Qt::Key_ZoomIn; + + case 0x000000a9: // KEYCODE_ZOOM_OUT + return Qt::Key_ZoomOut; + + case 0x000000af: // KEYCODE_CAPTIONS + return Qt::Key_Subtitle; + + case 0x000000d0: // KEYCODE_CALENDAR + return Qt::Key_Calendar; + + case 0x000000d1: // KEYCODE_MUSIC + return Qt::Key_Music; + + case 0x000000d2: // KEYCODE_CALCULATOR + return Qt::Key_Calculator; + case 0x00000000: // KEYCODE_UNKNOWN - case 0x00000011: // KEYCODE_STAR ?!?!? - case 0x00000012: // KEYCODE_POUND ?!?!? + return Qt::Key_unknown; + case 0x00000053: // KEYCODE_NOTIFICATION ?!?!? case 0x0000004f: // KEYCODE_HEADSETHOOK ?!?!? case 0x00000044: // KEYCODE_GRAVE ?!?!? - case 0x00000050: // KEYCODE_FOCUS ?!?!? return Qt::Key_Any; default: diff --git a/src/plugins/platforms/directfb/qdirectfbconvenience.cpp b/src/plugins/platforms/directfb/qdirectfbconvenience.cpp index 5b4c958616..b56d75a16e 100644 --- a/src/plugins/platforms/directfb/qdirectfbconvenience.cpp +++ b/src/plugins/platforms/directfb/qdirectfbconvenience.cpp @@ -282,9 +282,12 @@ QDirectFbKeyMap::QDirectFbKeyMap() insert(DIKS_MENU , Qt::Key_Menu); insert(DIKS_HELP , Qt::Key_Help); + insert(DIKS_CD , Qt::Key_CD); insert(DIKS_INTERNET , Qt::Key_HomePage); insert(DIKS_MAIL , Qt::Key_LaunchMail); insert(DIKS_FAVORITES , Qt::Key_Favorites); + insert(DIKS_PHONE , Qt::Key_Phone); + insert(DIKS_TIME , Qt::Key_Time); insert(DIKS_RED , Qt::Key_Red); insert(DIKS_GREEN , Qt::Key_Green); @@ -307,6 +310,7 @@ QDirectFbKeyMap::QDirectFbKeyMap() insert(DIKS_NEXT , Qt::Key_MediaNext); insert(DIKS_REWIND , Qt::Key_AudioRewind); insert(DIKS_FASTFORWARD , Qt::Key_AudioForward); + insert(DIKS_SUBTITLE , Qt::Key_Subtitle); insert(DIKS_F1 , Qt::Key_F1); insert(DIKS_F2 , Qt::Key_F2); -- cgit v1.2.3 From c1417023d502200ef2b68cf46d72e6496d787020 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Thu, 10 Oct 2013 13:34:42 +0200 Subject: Correct PrefixPath on iOS. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The iOS bundles are "flat", do not insert "/Contents/" like we do on OS X. Change-Id: I4e848f4425482b92cac04d940e5bce06b7199fc6 Reviewed-by: Tor Arne Vestbø --- src/corelib/global/qlibraryinfo.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp index 8d681f0c4c..33d7b71cff 100644 --- a/src/corelib/global/qlibraryinfo.cpp +++ b/src/corelib/global/qlibraryinfo.cpp @@ -442,7 +442,11 @@ QLibraryInfo::rawLocation(LibraryLocation loc, PathGroup group) QCFType urlRef = CFBundleCopyBundleURL(bundleRef); if (urlRef) { QCFString path = CFURLCopyFileSystemPath(urlRef, kCFURLPOSIXPathStyle); +#ifdef Q_OS_MACX return QDir::cleanPath(QString(path) + QLatin1String("/Contents/") + ret); +#else + return QDir::cleanPath(QString(path) + QLatin1Char('/') + ret); // iOS +#endif } } #endif -- cgit v1.2.3 From 52d0f9b1e4e808fce900a99f23ef8c4702306e61 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Mon, 14 Oct 2013 20:40:21 +0200 Subject: Remove stray semicolon MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I6f2d6df5eac2ce66bf2140c2e96c8945cdb439ef Reviewed-by: Jan Arve Sæther --- src/plugins/accessible/widgets/simplewidgets.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/accessible/widgets/simplewidgets.cpp b/src/plugins/accessible/widgets/simplewidgets.cpp index e3e614d700..6c8e4925cd 100644 --- a/src/plugins/accessible/widgets/simplewidgets.cpp +++ b/src/plugins/accessible/widgets/simplewidgets.cpp @@ -605,7 +605,7 @@ QString QAccessibleLineEdit::text(QAccessible::Text t) const break; } if (str.isEmpty()) - str = QAccessibleWidget::text(t);; + str = QAccessibleWidget::text(t); return qt_accStripAmp(str); } -- cgit v1.2.3 From 23833629fa7d3aa510267d314dd422b3b3ea0de3 Mon Sep 17 00:00:00 2001 From: "Richard J. Moore" Date: Sun, 13 Oct 2013 11:29:11 +0100 Subject: Update changelog for QtNetwork 5.2. Change-Id: I3d6c416cd3213282224ea9251a5506b1f0713b24 Reviewed-by: Kurt Pattyn Reviewed-by: Sergio Ahumada --- dist/changes-5.2.0 | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/dist/changes-5.2.0 b/dist/changes-5.2.0 index a8a3e581de..ea15295cad 100644 --- a/dist/changes-5.2.0 +++ b/dist/changes-5.2.0 @@ -84,3 +84,20 @@ QtGui related to session management. For platform that don't support this feature the default behavior has not changed. Both X11 and Windows session management are supported. + +QtNetwork +--------- + +- The minimum support openssl version has been increased to openssl 1.0. The + code to support older versions has not been removed, but is no longer + supported. + +- An off-by-one error in NTLM proxy authentication has been fixed. + +- Various improvements to reduce the memory used by qtnetwork have been made. + +- Improved support for HTTP proxy authentication. + +- Support for preconnecting to servers before making HTTP and HTTPS + connections. This allows for much reduced latency when the hosts to be + connected to are known. -- cgit v1.2.3 From 4684f2179be7182d32d50067e1ca0fa87619792e Mon Sep 17 00:00:00 2001 From: Jan Arve Saether Date: Fri, 4 Oct 2013 15:32:53 +0200 Subject: Change return type of imagePosition to QPoint QAccessibleImageInterface already has an API to return the size of the image. This function ensures that their API's are not overlapping. Alternatively, we could merge both functions into QAccessibleImageInterface::imageRect(), but the assumption is that images change position more often than their size. Change-Id: I55c25cdff187b9f497828f04cfd5f969cfbc451f Reviewed-by: Frederik Gladhorn --- src/gui/accessible/qaccessible.h | 2 +- src/plugins/accessible/widgets/simplewidgets.cpp | 8 ++++---- src/plugins/accessible/widgets/simplewidgets.h | 2 +- tests/auto/other/qaccessibility/tst_qaccessibility.cpp | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/gui/accessible/qaccessible.h b/src/gui/accessible/qaccessible.h index ff3e910883..d5b0af550e 100644 --- a/src/gui/accessible/qaccessible.h +++ b/src/gui/accessible/qaccessible.h @@ -589,7 +589,7 @@ public: virtual QString imageDescription() const = 0; virtual QSize imageSize() const = 0; - virtual QRect imagePosition() const = 0; + virtual QPoint imagePosition() const = 0; }; diff --git a/src/plugins/accessible/widgets/simplewidgets.cpp b/src/plugins/accessible/widgets/simplewidgets.cpp index 6c8e4925cd..1dac199a09 100644 --- a/src/plugins/accessible/widgets/simplewidgets.cpp +++ b/src/plugins/accessible/widgets/simplewidgets.cpp @@ -474,16 +474,16 @@ QSize QAccessibleDisplay::imageSize() const } /*! \internal */ -QRect QAccessibleDisplay::imagePosition() const +QPoint QAccessibleDisplay::imagePosition() const { QLabel *label = qobject_cast(widget()); if (!label) - return QRect(); + return QPoint(); const QPixmap *pixmap = label->pixmap(); if (!pixmap) - return QRect(); + return QPoint(); - return QRect(label->mapToGlobal(label->pos()), label->size()); + return QPoint(label->mapToGlobal(label->pos())); } #ifndef QT_NO_GROUPBOX diff --git a/src/plugins/accessible/widgets/simplewidgets.h b/src/plugins/accessible/widgets/simplewidgets.h index 66b4c2bd3e..6024788048 100644 --- a/src/plugins/accessible/widgets/simplewidgets.h +++ b/src/plugins/accessible/widgets/simplewidgets.h @@ -110,7 +110,7 @@ public: // QAccessibleImageInterface QString imageDescription() const Q_DECL_OVERRIDE; QSize imageSize() const Q_DECL_OVERRIDE; - QRect imagePosition() const Q_DECL_OVERRIDE; + QPoint imagePosition() const Q_DECL_OVERRIDE; }; #ifndef QT_NO_GROUPBOX diff --git a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp index c4a0d9c76c..73bf4aab6a 100644 --- a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp +++ b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp @@ -3295,7 +3295,7 @@ void tst_QAccessibility::labelTest() QCOMPARE(imageInterface->imageSize(), testPixmap.size()); QCOMPARE(imageInterface->imageDescription(), QString::fromLatin1("Test Description")); const QPoint labelPos = imageLabel.mapToGlobal(QPoint(0,0)); - QCOMPARE(imageInterface->imagePosition().topLeft(), labelPos); + QCOMPARE(imageInterface->imagePosition(), labelPos); QTestAccessibility::clearEvents(); } -- cgit v1.2.3 From 89c01c3242079f12421da234f2a21abfee4b71e1 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Tue, 17 Sep 2013 20:07:37 +0200 Subject: Only emit messageChanged() if the message has actually changed This fixes QStatusBar so it is back to the original behavior of only emitting the signal when the message has changed. The intention of the code that caused this to break in the first place is kept intact. Change-Id: I2f57c2abec01246ed924626ad954ac9ff9889855 Reviewed-by: Friedemann Kleint --- src/widgets/widgets/qstatusbar.cpp | 5 ++-- .../widgets/widgets/qstatusbar/tst_qstatusbar.cpp | 27 ++++++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/widgets/widgets/qstatusbar.cpp b/src/widgets/widgets/qstatusbar.cpp index 86fd10699c..7b1d66cf0d 100644 --- a/src/widgets/widgets/qstatusbar.cpp +++ b/src/widgets/widgets/qstatusbar.cpp @@ -551,8 +551,6 @@ void QStatusBar::showMessage(const QString &message, int timeout) { Q_D(QStatusBar); - d->tempItem = message; - if (timeout > 0) { if (!d->timer) { d->timer = new QTimer(this); @@ -563,6 +561,9 @@ void QStatusBar::showMessage(const QString &message, int timeout) delete d->timer; d->timer = 0; } + if (d->tempItem == message) + return; + d->tempItem = message; hideOrShow(); } diff --git a/tests/auto/widgets/widgets/qstatusbar/tst_qstatusbar.cpp b/tests/auto/widgets/widgets/qstatusbar/tst_qstatusbar.cpp index 3bdf583153..a301d51c4c 100644 --- a/tests/auto/widgets/widgets/qstatusbar/tst_qstatusbar.cpp +++ b/tests/auto/widgets/widgets/qstatusbar/tst_qstatusbar.cpp @@ -74,6 +74,7 @@ private slots: void task194017_hiddenWidget(); void QTBUG4334_hiddenOnMaximizedWindow(); void QTBUG25492_msgtimeout(); + void messageChangedSignal(); private: QStatusBar *testWidget; @@ -95,6 +96,8 @@ void tst_QStatusBar::init() QWidget *item1 = new QWidget(testWidget); testWidget->addWidget(item1); + // currentMessage needs to be null as the code relies on this + currentMessage = QString(); } void tst_QStatusBar::cleanup() @@ -316,6 +319,30 @@ void tst_QStatusBar::QTBUG25492_msgtimeout() QCOMPARE(testWidget->currentMessage(), currentMessage); } +void tst_QStatusBar::messageChangedSignal() +{ + QVERIFY(testWidget->currentMessage().isNull()); + QVERIFY(currentMessage.isNull()); + testWidget->show(); + + QSignalSpy spy(testWidget, SIGNAL(messageChanged(QString))); + testWidget->showMessage("Ready", 0); + QCOMPARE(testWidget->currentMessage(), QString("Ready")); + QCOMPARE(testWidget->currentMessage(), currentMessage); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.takeFirst().at(0).toString(), currentMessage); + testWidget->clearMessage(); + QCOMPARE(testWidget->currentMessage(), QString()); + QCOMPARE(testWidget->currentMessage(), currentMessage); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.takeFirst().at(0).toString(), currentMessage); + testWidget->showMessage("Ready", 0); + testWidget->showMessage("Ready", 0); + QCOMPARE(testWidget->currentMessage(), QString("Ready")); + QCOMPARE(testWidget->currentMessage(), currentMessage); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.takeFirst().at(0).toString(), currentMessage); +} QTEST_MAIN(tst_QStatusBar) #include "tst_qstatusbar.moc" -- cgit v1.2.3 From 816e7f11f192b199e62c7128efedbc63c05ffd79 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Wed, 9 Oct 2013 12:08:43 +0200 Subject: Avoid other threads blocking for Q_GLOBAL_STATIC constructor on Mac The compiler inserts __cxa_guard_acquire, __cxa_guard_release calls around the initialization of local static objects to make the initialization thread safe. However, the implementation of _cxa_guard_acquire in Apple's libc++abi uses a global lock, which means that only one thread can initialize a local static variable at a time. This can be a problem if e.g. the constructor of the variable is blocking while waiting for another thread ... This behavior has caused issues so far in webkit and the qml debugging infrastructure. Better avoid it by using our custom lock implementation. __cxa_guard_acquire implementation: http://www.opensource.apple.com/source/libcppabi/libcppabi-24.2/src/cxa_guard.cxx Task-number: QTBUG-33967 Change-Id: I0d50531ed91ddd074aa07f61f6bf7791e23d990b Reviewed-by: Olivier Goffart Reviewed-by: Thiago Macieira --- src/corelib/global/qglobalstatic.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/corelib/global/qglobalstatic.h b/src/corelib/global/qglobalstatic.h index 5d0b1e8514..ad39452cf4 100644 --- a/src/corelib/global/qglobalstatic.h +++ b/src/corelib/global/qglobalstatic.h @@ -57,11 +57,16 @@ enum GuardValues { }; } -#if defined(QT_NO_THREAD) || defined(Q_CC_GNU) +#if defined(QT_NO_THREAD) || (defined(Q_CC_GNU) && !defined(Q_OS_MAC)) // some compilers support thread-safe statics // The IA-64 C++ ABI requires this, so we know that all GCC versions since 3.4 // support it. C++11 also requires this behavior. -// Clang and Intel CC masquerade as GCC when compiling on Linux and Mac OS X. +// Clang and Intel CC masquerade as GCC when compiling on Linux. +// +// Apple's libc++abi however uses a global lock for initializing local statics, +// which will block other threads also trying to initialize a local static +// until the constructor returns ... +// We better avoid these kind of problems by using our own locked implementation. #define Q_GLOBAL_STATIC_INTERNAL(ARGS) \ Q_DECL_HIDDEN inline Type *innerFunction() \ -- cgit v1.2.3 From dd2e1c58a76d946f8e7b6acb8dc14c52633e703a Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Mon, 14 Oct 2013 14:10:33 +0200 Subject: Document %{category} for qSetMessagePattern Change-Id: Ib6ad515ce4ba27d501538ba45fd65e60ce5332df Reviewed-by: Jerome Pasion Reviewed-by: hjk --- src/corelib/global/qlogging.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp index b9b5173881..7a759ef8f5 100644 --- a/src/corelib/global/qlogging.cpp +++ b/src/corelib/global/qlogging.cpp @@ -1108,6 +1108,7 @@ void qErrnoWarning(int code, const char *msg, ...) \table \header \li Placeholder \li Description \row \li \c %{appname} \li QCoreApplication::applicationName() + \row \li \c %{category} \li Logging category \row \li \c %{file} \li Path to source file \row \li \c %{function} \li Function \row \li \c %{line} \li Line in source file -- cgit v1.2.3 From 0008a6f4000674020db96ff4475094d049d094f6 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Mon, 14 Oct 2013 17:04:05 +0200 Subject: Fix compilation of ANGLE on MinGW This broke with commit 89f9bc9c5f873d6763e35d2f92d31c28f8fb5262. Task-number: QTBUG-34080 Change-Id: Ib3c7a3c90db7dc04f417eba4c1328390f45e5e5f Reviewed-by: Friedemann Kleint --- src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp | 2 +- .../patches/0001-Fix-compilation-for-MSVC-2008-and-std-tuple.patch | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp index 95a6961e7b..51d7f0b653 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp @@ -84,7 +84,7 @@ bool IndexRangeCache::IndexRange::operator<(const IndexRange& rhs) const #if defined(_MSC_VER) && _MSC_VER < 1600 return std::tr1::make_tuple(type, offset, count) < std::tr1::make_tuple(rhs.type, rhs.offset, rhs.count); #else - return std::make_tuple(type, offset, count) < std::tr1::make_tuple(rhs.type, rhs.offset, rhs.count); + return std::make_tuple(type, offset, count) < std::make_tuple(rhs.type, rhs.offset, rhs.count); #endif } diff --git a/src/angle/patches/0001-Fix-compilation-for-MSVC-2008-and-std-tuple.patch b/src/angle/patches/0001-Fix-compilation-for-MSVC-2008-and-std-tuple.patch index 0e72c57be6..2fa23aed8f 100644 --- a/src/angle/patches/0001-Fix-compilation-for-MSVC-2008-and-std-tuple.patch +++ b/src/angle/patches/0001-Fix-compilation-for-MSVC-2008-and-std-tuple.patch @@ -22,7 +22,7 @@ index 610a5ef..95a6961 100644 +#if defined(_MSC_VER) && _MSC_VER < 1600 + return std::tr1::make_tuple(type, offset, count) < std::tr1::make_tuple(rhs.type, rhs.offset, rhs.count); +#else -+ return std::make_tuple(type, offset, count) < std::tr1::make_tuple(rhs.type, rhs.offset, rhs.count); ++ return std::make_tuple(type, offset, count) < std::make_tuple(rhs.type, rhs.offset, rhs.count); +#endif } -- cgit v1.2.3 From 52c8d9ffbabc05c8f6cd7d2a21c109afb6aae8d1 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 15 Oct 2013 12:55:11 +0200 Subject: linuxfb: Adapt to initialize() pattern MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Migrate to the new 5.2 pattern: Prevent relying on the event dispatcher in the constructor by performing initialization later in initialize() instead. Change-Id: Ifa6024affc35e995d6e33a63fa813da9df0c491b Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp | 11 ++++++++--- src/plugins/platforms/linuxfb/qlinuxfbintegration.h | 14 ++++++++------ src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp | 8 ++++---- src/plugins/platforms/linuxfb/qlinuxfbscreen.h | 5 +++-- 4 files changed, 23 insertions(+), 15 deletions(-) diff --git a/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp b/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp index aa2687da30..977df8abd0 100644 --- a/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp +++ b/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp @@ -56,9 +56,8 @@ QT_BEGIN_NAMESPACE QLinuxFbIntegration::QLinuxFbIntegration(const QStringList ¶mList) : m_fontDb(new QGenericUnixFontDatabase()) { - m_primaryScreen = new QLinuxFbScreen; - if (m_primaryScreen->initialize(paramList)) - screenAdded(m_primaryScreen); + m_primaryScreen = new QLinuxFbScreen(paramList); + screenAdded(m_primaryScreen); } QLinuxFbIntegration::~QLinuxFbIntegration() @@ -66,6 +65,12 @@ QLinuxFbIntegration::~QLinuxFbIntegration() delete m_primaryScreen; } +void QLinuxFbIntegration::initialize() +{ + if (!m_primaryScreen->initialize()) + qWarning("linuxfb: Failed to initialize screen"); +} + bool QLinuxFbIntegration::hasCapability(QPlatformIntegration::Capability cap) const { switch (cap) { diff --git a/src/plugins/platforms/linuxfb/qlinuxfbintegration.h b/src/plugins/platforms/linuxfb/qlinuxfbintegration.h index 6de9ac9992..a213f83c6f 100644 --- a/src/plugins/platforms/linuxfb/qlinuxfbintegration.h +++ b/src/plugins/platforms/linuxfb/qlinuxfbintegration.h @@ -56,14 +56,16 @@ public: QLinuxFbIntegration(const QStringList ¶mList); ~QLinuxFbIntegration(); - bool hasCapability(QPlatformIntegration::Capability cap) const; + void initialize() Q_DECL_OVERRIDE; + bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE; + + QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const Q_DECL_OVERRIDE; + QPlatformWindow *createPlatformWindow(QWindow *window) const Q_DECL_OVERRIDE; + QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const Q_DECL_OVERRIDE; + QAbstractEventDispatcher *createEventDispatcher() const Q_DECL_OVERRIDE; + QPlatformFontDatabase *fontDatabase() const Q_DECL_OVERRIDE; - QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const; - QPlatformWindow *createPlatformWindow(QWindow *window) const; - QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const; - QAbstractEventDispatcher *createEventDispatcher() const; QList screens() const; - QPlatformFontDatabase *fontDatabase() const; private: QLinuxFbScreen *m_primaryScreen; diff --git a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp index 6a2d767723..4f9284da7f 100644 --- a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp +++ b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp @@ -296,8 +296,8 @@ static void blankScreen(int fd, bool on) ioctl(fd, FBIOBLANK, on ? VESA_POWERDOWN : VESA_NO_BLANKING); } -QLinuxFbScreen::QLinuxFbScreen() - : mFbFd(-1), mBlitter(0) +QLinuxFbScreen::QLinuxFbScreen(const QStringList &args) + : mArgs(args), mFbFd(-1), mBlitter(0) { } @@ -316,7 +316,7 @@ QLinuxFbScreen::~QLinuxFbScreen() delete mBlitter; } -bool QLinuxFbScreen::initialize(const QStringList &args) +bool QLinuxFbScreen::initialize() { QRegExp ttyRx(QLatin1String("tty=(.*)")); QRegExp fbRx(QLatin1String("fb=(.*)")); @@ -330,7 +330,7 @@ bool QLinuxFbScreen::initialize(const QStringList &args) bool doSwitchToGraphicsMode = true; // Parse arguments - foreach (const QString &arg, args) { + foreach (const QString &arg, mArgs) { if (arg == QLatin1String("nographicsmodeswitch")) doSwitchToGraphicsMode = false; else if (sizeRx.indexIn(arg) != -1) diff --git a/src/plugins/platforms/linuxfb/qlinuxfbscreen.h b/src/plugins/platforms/linuxfb/qlinuxfbscreen.h index d34104c6e1..32cd263063 100644 --- a/src/plugins/platforms/linuxfb/qlinuxfbscreen.h +++ b/src/plugins/platforms/linuxfb/qlinuxfbscreen.h @@ -53,15 +53,16 @@ class QLinuxFbScreen : public QFbScreen { Q_OBJECT public: - QLinuxFbScreen(); + QLinuxFbScreen(const QStringList &args); ~QLinuxFbScreen(); - bool initialize(const QStringList &args); + bool initialize(); public slots: QRegion doRedraw(); private: + QStringList mArgs; int mFbFd; int mTtyFd; -- cgit v1.2.3 From a3a1bd755fc69278f7fcdc7127aaf2a48e1a4980 Mon Sep 17 00:00:00 2001 From: Tasuku Suzuki Date: Mon, 7 Oct 2013 10:45:26 +0900 Subject: Fix build when fwrite() is declared with attribute warn_unused_result Task-number: QTBUG-33921 Change-Id: I58dded1f54239e4c5cfd5f4f5c1655dbf879b2c8 Reviewed-by: Olivier Goffart Reviewed-by: Thiago Macieira --- src/tools/moc/generator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp index 34d3c06e97..b39a3b5e9f 100644 --- a/src/tools/moc/generator.cpp +++ b/src/tools/moc/generator.cpp @@ -310,7 +310,7 @@ void Generator::generateCode() int escapeLen = lengthOfEscapeSequence(s, backSlashPos); spanLen = qBound(spanLen, backSlashPos + escapeLen - idx, s.length() - idx); } - fwrite(s.constData() + idx, 1, spanLen, out); + fprintf(out, "%.*s", spanLen, s.constData() + idx); idx += spanLen; col += spanLen; } -- cgit v1.2.3 From 8178a6cab111fb0da9e637bf41464aba66d57609 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 15 Oct 2013 10:18:22 +0200 Subject: Add missing operators QMargins -=,+= (int). Task-number: QTBUG-34079 Change-Id: If61cc01ba70345b01f13072769d3a38f23e8cefc Reviewed-by: Thiago Macieira --- src/corelib/tools/qmargins.h | 18 ++++++++++++++++++ tests/auto/corelib/tools/qmargins/tst_qmargins.cpp | 6 ++++++ 2 files changed, 24 insertions(+) diff --git a/src/corelib/tools/qmargins.h b/src/corelib/tools/qmargins.h index 0d68be961e..ad5e94cefe 100644 --- a/src/corelib/tools/qmargins.h +++ b/src/corelib/tools/qmargins.h @@ -242,6 +242,24 @@ inline QMargins &QMargins::operator-=(const QMargins &margins) return *this = *this - margins; } +inline QMargins &QMargins::operator+=(int margin) +{ + m_left += margin; + m_top += margin; + m_right += margin; + m_bottom += margin; + return *this; +} + +inline QMargins &QMargins::operator-=(int margin) +{ + m_left -= margin; + m_top -= margin; + m_right -= margin; + m_bottom -= margin; + return *this; +} + inline QMargins &QMargins::operator*=(int factor) { return *this = *this * factor; diff --git a/tests/auto/corelib/tools/qmargins/tst_qmargins.cpp b/tests/auto/corelib/tools/qmargins/tst_qmargins.cpp index d22e771b79..ec83740196 100644 --- a/tests/auto/corelib/tools/qmargins/tst_qmargins.cpp +++ b/tests/auto/corelib/tools/qmargins/tst_qmargins.cpp @@ -93,6 +93,12 @@ void tst_QMargins::operators() a -= m2; QCOMPARE(a, subtracted); + QMargins h = m1; + h += 2; + QCOMPARE(h, QMargins(14, 16, 18, 20)); + h -= 2; + QCOMPARE(h, m1); + const QMargins doubled = m1 * 2; QCOMPARE(doubled, QMargins(24, 28, 32, 36)); QCOMPARE(2 * m1, doubled); -- cgit v1.2.3 From b5d01a9dfc42c4da7aec7123b9839de52b8335ff Mon Sep 17 00:00:00 2001 From: Jerome Pasion Date: Fri, 11 Oct 2013 16:40:31 +0200 Subject: Doc: Adding "\keyword Signals and Slots" to "Signals & Slots" page. -many articles link to the page using the "and" or the "&" version, causing missing links. Change-Id: I6447149befce169cfafff29164172290a7c15f0c Reviewed-by: Sze Howe Koh Reviewed-by: Leena Miettinen Reviewed-by: Jerome Pasion --- src/corelib/doc/src/objectmodel/signalsandslots.qdoc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/corelib/doc/src/objectmodel/signalsandslots.qdoc b/src/corelib/doc/src/objectmodel/signalsandslots.qdoc index b86aae830f..dd93b80cae 100644 --- a/src/corelib/doc/src/objectmodel/signalsandslots.qdoc +++ b/src/corelib/doc/src/objectmodel/signalsandslots.qdoc @@ -28,6 +28,7 @@ /*! \page signalsandslots.html \title Signals & Slots + \keyword Signals and Slots \ingroup qt-basic-concepts \brief An overview of Qt's signals and slots inter-object communication mechanism. -- cgit v1.2.3 From 557fe401ac037badcc59f54f3a721071ffde0d07 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Tue, 15 Oct 2013 12:26:24 +0200 Subject: Clean up support library linkage on Android MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * The explicitly linked support libraries like gnustl_shared, etc. can be linked as private libs, there's no need for them to show up in the .prl files of our libraries. * Removed the explicit linkage against libsupc++, which is a static library whos symbols are also available in libgnustl_shared. It is only needed when linking against gnustl_static, which we fortunately don't do. For QtQml on Android this is more than just cleanup. Without the first change, the libgnustl_shared comes early on in the link line, because it is a dependency of for example Qt5Network. Anything that qml.pro itself adds to LIBS comes afterwards. That is not intended, we want libgnustl_shared to come at the end of the link line, in order to make sure that the linker finds an overriding symbol from another library earlier in the link line first. The explicit linkage against libsupc++ affects the same, as that's the library that contains the symbol we want to override locally (__cxa_end_cleanup). (needed for QTBUG-33892) Change-Id: Id6dff733d6610ae8b15aa72f9cf60ae2c7834194 Reviewed-by: Tor Arne Vestbø Reviewed-by: BogDan Vatra --- mkspecs/android-g++/qmake.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkspecs/android-g++/qmake.conf b/mkspecs/android-g++/qmake.conf index 0df2509257..11d62a1efb 100644 --- a/mkspecs/android-g++/qmake.conf +++ b/mkspecs/android-g++/qmake.conf @@ -178,7 +178,7 @@ QMAKE_LFLAGS_NOUNDEF = -Wl,--no-undefined QMAKE_LFLAGS_RPATH = -Wl,-rpath= QMAKE_LFLAGS_RPATHLINK = -Wl,-rpath-link= -QMAKE_LIBS = -lgnustl_shared -lsupc++ -llog -lz -lm -ldl -lc -lgcc +QMAKE_LIBS_PRIVATE = -lgnustl_shared -llog -lz -lm -ldl -lc -lgcc QMAKE_LIBS_X11 = QMAKE_LIBS_THREAD = QMAKE_LIBS_EGL = -lEGL -- cgit v1.2.3 From b7d288271517f2e4cba77ddfae0d0c4c0b3cd1c7 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 15 Oct 2013 12:49:45 +0200 Subject: linuxfb: Do not crash with GL windows We will show an error message saying no platform context is available but the crash (due to GL windows having a null backingstore) is not desirable. Change-Id: Iba3a61bfc4eeeb89b4a0017a58c87a7dbd0895e7 Reviewed-by: Andy Nichols --- src/platformsupport/fbconvenience/qfbscreen.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/platformsupport/fbconvenience/qfbscreen.cpp b/src/platformsupport/fbconvenience/qfbscreen.cpp index 4ef035cf50..37d16ddeb6 100644 --- a/src/platformsupport/fbconvenience/qfbscreen.cpp +++ b/src/platformsupport/fbconvenience/qfbscreen.cpp @@ -258,8 +258,9 @@ QRegion QFbScreen::doRedraw() QRect windowRect = mWindowStack[layerIndex]->geometry().translated(-screenOffset); QRect windowIntersect = rect.translated(-windowRect.left(), -windowRect.top()); - mCompositePainter->drawImage(rect, mWindowStack[layerIndex]->backingStore()->image(), - windowIntersect); + QFbBackingStore *backingStore = mWindowStack[layerIndex]->backingStore(); + if (backingStore) + mCompositePainter->drawImage(rect, backingStore->image(), windowIntersect); if (firstLayer) { firstLayer = false; } -- cgit v1.2.3 From 0a19ee0aea330c2f46c8fe7cc461adb1060ec6df Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Tue, 15 Oct 2013 15:09:17 +0200 Subject: set the title of the user time window not the application window 51c28cad67077500f63dbe8c0060ed19cf340c0d resulted in setting the title of the wrong window. Task-number: QTBUG-34048 Change-Id: Ia22d563e0ba9b0e074ef79ae5169c1627369c70d Reviewed-by: Laszlo Agocs --- src/plugins/platforms/xcb/qxcbwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 6d986ba601..aa53093868 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -1148,7 +1148,7 @@ void QXcbWindow::updateNetWmUserTime(xcb_timestamp_t timestamp) QByteArray ba("Qt NET_WM user time window"); Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, - m_window, + m_netWmUserTimeWindow, atom(QXcbAtom::_NET_WM_NAME), atom(QXcbAtom::UTF8_STRING), 8, -- cgit v1.2.3 From 688b006cc8d8d4d9ce1f29049f96d4d590bb60d7 Mon Sep 17 00:00:00 2001 From: John Layt Date: Tue, 15 Oct 2013 16:25:22 +0200 Subject: QTimeZone - Fix finding Linux System Time Zone Extract the correct length sub-string from the /etc/sysconfig/clock file Change-Id: I37b4f625a51b172ed11ecefbd1b7dc562c5bb89d Reviewed-by: Thiago Macieira --- src/corelib/tools/qtimezoneprivate_tz.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/tools/qtimezoneprivate_tz.cpp b/src/corelib/tools/qtimezoneprivate_tz.cpp index 62b8f5f7b6..4bf19178fa 100644 --- a/src/corelib/tools/qtimezoneprivate_tz.cpp +++ b/src/corelib/tools/qtimezoneprivate_tz.cpp @@ -883,9 +883,9 @@ QByteArray QTzTimeZonePrivate::systemTimeZoneId() const while (olsenId.isEmpty() && !ts.atEnd() && ts.status() == QTextStream::Ok) { line = ts.readLine(); if (line.left(5) == QStringLiteral("ZONE=")) { - olsenId = line.mid(6, line.size() - 2).toUtf8(); + olsenId = line.mid(6, line.size() - 7).toUtf8(); } else if (line.left(9) == QStringLiteral("TIMEZONE=")) { - olsenId = line.mid(6, line.size() - 2).toUtf8(); + olsenId = line.mid(10, line.size() - 11).toUtf8(); } } } -- cgit v1.2.3 From 6cdc033c61eeca5303fd271d28003f8617f9f830 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 9 Oct 2013 11:38:44 -0700 Subject: Use the fast operator+ (in the form of operator%) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QStringBuilder will precalculate the size of the string for us, which avoids extra realloc() and moving data around. Change-Id: I4e31964bb9bfffbe2083b3cb8c120e602160dfd8 Reviewed-by: David Faure Reviewed-by: JÄ™drzej Nowacki Reviewed-by: Kevin Ottens --- src/corelib/io/qlockfile_unix.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/corelib/io/qlockfile_unix.cpp b/src/corelib/io/qlockfile_unix.cpp index de21ee217a..dc8817706c 100644 --- a/src/corelib/io/qlockfile_unix.cpp +++ b/src/corelib/io/qlockfile_unix.cpp @@ -142,13 +142,10 @@ QLockFile::LockError QLockFilePrivate::tryLock_sys() { // Assemble data, to write in a single call to write // (otherwise we'd have to check every write call) - QByteArray fileData; - fileData += QByteArray::number(QCoreApplication::applicationPid()); - fileData += '\n'; - fileData += qAppName().toUtf8(); - fileData += '\n'; - fileData += localHostName().toUtf8(); - fileData += '\n'; + // Use operator% from the fast builder to avoid multiple memory allocations. + QByteArray fileData = QByteArray::number(QCoreApplication::applicationPid()) % '\n' + % qAppName().toUtf8() % '\n' + % localHostName().toUtf8() % '\n'; const QByteArray lockFileName = QFile::encodeName(fileName); const int fd = qt_safe_open(lockFileName.constData(), O_WRONLY | O_CREAT | O_EXCL, 0644); -- cgit v1.2.3 From 74f2a1bd472802cc93e416d2916d0e798e199515 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 7 Oct 2013 12:36:34 -0700 Subject: Fix the printing of qmake's output when OPT_VERBOSE=yes Don't discard stdout, it might contain important information. For example, if qmake crashes, the segfault or similar notification comes to stdout. Change-Id: I53def75f37f134544922cf01b4f2ba7c903351cb Reviewed-by: Oswald Buddenhagen --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index 4e0d6f1e07..adcc64bba2 100755 --- a/configure +++ b/configure @@ -4230,7 +4230,7 @@ fi #------------------------------------------------------------------------------- # Verify makespec #------------------------------------------------------------------------------- -QMAKE_OUTPUT=`$outpath/bin/qmake -E -nocache -spec "$XQMAKESPEC" "QT=" $DEV_NULL 2>&1 >/dev/null` +QMAKE_OUTPUT=`$outpath/bin/qmake -E -nocache -spec "$XQMAKESPEC" "QT=" $DEV_NULL 2>&1` if [ $? != "0" ]; then echo "Failed to process makespec for platform '$XPLATFORM'" if [ "$OPT_VERBOSE" = "yes" ]; then -- cgit v1.2.3 From 704616605b571f126bce59243c8bc3be48f5ace8 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 14 Oct 2013 14:05:57 -0700 Subject: Remove compatibility support for sealed/override in C++/CLI Those features have slightly different behavior as the C++11 keywords that MSVC 2012 officially supports. When compiling in C++/CLI mode, the "virtual" keyword must be present too. We have not actually tested whether the official MSVC 2012 support for C++/CLI still requires the virtual keyword. This is just going on the assumption that C++/CLI follows the C++11 spec. Task-number: QTBUG-34019 Change-Id: I148a443bfbff985033c555f5a9cfcd5be7f5f106 Reviewed-by: Olivier Goffart Reviewed-by: Lars Knoll --- src/corelib/global/qcompilerdetection.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h index a388bdb96f..280c5066a6 100644 --- a/src/corelib/global/qcompilerdetection.h +++ b/src/corelib/global/qcompilerdetection.h @@ -696,15 +696,20 @@ # if _MSC_VER >= 1400 /* C++11 features supported in VC8 = VC2005: */ # define Q_COMPILER_VARIADIC_MACROS + +# ifndef __cplusplus_cli /* 2005 supports the override and final contextual keywords, in the same positions as the C++11 variants, but 'final' is called 'sealed' instead: http://msdn.microsoft.com/en-us/library/0w2w91tf%28v=vs.80%29.aspx + The behavior is slightly different in C++/CLI, which requires the + "virtual" keyword to be present too, so don't define for that. So don't define Q_COMPILER_EXPLICIT_OVERRIDES (since it's not the same as the C++11 version), but define the Q_DECL_* flags accordingly: */ # define Q_DECL_OVERRIDE override # define Q_DECL_FINAL sealed +# endif # endif # if _MSC_VER >= 1600 /* C++11 features supported in VC10 = VC2010: */ -- cgit v1.2.3 From 6c5e6a030dc49f36a5d4f2846fe78daf3d02a03d Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 4 Oct 2013 15:23:54 -0700 Subject: Fix loading of libresolv when the .so file (not .so.2) isn't installed glibc is nice to us and provides a #define with the actual name. On most Linux systems, the .so file is installed only if the glibc-devel package is installed. For all of us Qt developers, it's installed. But for end users, it might not be. Change-Id: Id455371db91a074befd3bcd071f285c725d7e7e5 Reviewed-by: Ian Monroe Reviewed-by: Richard J. Moore --- src/network/kernel/qdnslookup_unix.cpp | 15 +++++++++++++-- src/network/kernel/qhostinfo_unix.cpp | 15 +++++++++++++-- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/network/kernel/qdnslookup_unix.cpp b/src/network/kernel/qdnslookup_unix.cpp index 729729d929..052c492f07 100644 --- a/src/network/kernel/qdnslookup_unix.cpp +++ b/src/network/kernel/qdnslookup_unix.cpp @@ -52,6 +52,10 @@ #include #include +#ifdef __GNU_LIBRARY__ +# include +#endif + QT_BEGIN_NAMESPACE #ifndef QT_NO_LIBRARY @@ -77,9 +81,16 @@ struct QDnsLookupStateDeleter static void resolveLibrary() { - QLibrary lib(QLatin1String("resolv")); + QLibrary lib; +#ifdef LIBRESOLV_SO + lib.setFileName(QStringLiteral(LIBRESOLV_SO)); if (!lib.load()) - return; +#endif + { + lib.setFileName(QLatin1String("resolv")); + if (!lib.load()) + return; + } local_dn_expand = dn_expand_proto(lib.resolve("__dn_expand")); if (!local_dn_expand) diff --git a/src/network/kernel/qhostinfo_unix.cpp b/src/network/kernel/qhostinfo_unix.cpp index 04daf2ecdd..dc2702b552 100644 --- a/src/network/kernel/qhostinfo_unix.cpp +++ b/src/network/kernel/qhostinfo_unix.cpp @@ -63,6 +63,10 @@ # include #endif +#ifdef __GNU_LIBRARY__ +# include +#endif + #if defined (QT_NO_GETADDRINFO) static QBasicMutex getHostByNameMutex; #endif @@ -93,9 +97,16 @@ static res_state_ptr local_res = 0; static void resolveLibrary() { #if !defined(QT_NO_LIBRARY) && !defined(Q_OS_QNX) - QLibrary lib(QLatin1String("resolv")); + QLibrary lib; +#ifdef LIBRESOLV_SO + lib.setFileName(QStringLiteral(LIBRESOLV_SO)); if (!lib.load()) - return; +#endif + { + lib.setFileName(QLatin1String("resolv")); + if (!lib.load()) + return; + } local_res_init = res_init_proto(lib.resolve("__res_init")); if (!local_res_init) -- cgit v1.2.3 From 6e4ea62b0a54d7f752edc2530b15461114eceef6 Mon Sep 17 00:00:00 2001 From: Matt Hoosier Date: Tue, 15 Oct 2013 08:30:16 -0500 Subject: Fix wide-char use in Posix collator Although the C++ language builds in the 'wchar_t' datatype, the library functions such as wcscmp() which manipulate them are not automatically available. For these, inclusion of the header is still required. This changeset fixes build breakage observed from failure to include the requisite system header for accessing wcscmp() and other related functions on non-GNU standard C++ library implementations. Change-Id: I5b2f9148ea011004e5dd00cf41698339db172de8 Reviewed-by: Thiago Macieira --- src/corelib/tools/qcollator_posix.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/corelib/tools/qcollator_posix.cpp b/src/corelib/tools/qcollator_posix.cpp index c6e589c174..a43618dcf1 100644 --- a/src/corelib/tools/qcollator_posix.cpp +++ b/src/corelib/tools/qcollator_posix.cpp @@ -44,6 +44,7 @@ #include "qstring.h" #include +#include QT_BEGIN_NAMESPACE @@ -141,7 +142,7 @@ bool QCollatorSortKey::operator<(const QCollatorSortKey &otherKey) const int QCollatorSortKey::compare(const QCollatorSortKey &otherKey) const { - return wcscmp(d->m_key.constData(), + return std::wcscmp(d->m_key.constData(), otherKey.d->m_key.constData()); } -- cgit v1.2.3 From fd82caf44f5e9a9ec206a8e93ebbdb24902e778e Mon Sep 17 00:00:00 2001 From: Sze Howe Koh Date: Thu, 10 Oct 2013 06:52:57 +0800 Subject: Doc: Expand thread technology comparisons Additions/Changes: - Add QML's WorkerScript type - Add QFuture + QFutureWatcher - Clarify differences between QtConcurrent::run() and the map/filter/ reduce functions - Reword table headings - QThreadPool accepts a priority parameter too (although it's not OS- level, unlike QThread) Rows removed from the table: - QThread can be "reused" and "task oriented" too, depending on the program design. It's hard to convey this in a table though, so I just removed it. - "High level" is ambiguous and doesn't really help readers choose a tool to use. Task-number: QTBUG-33360 Change-Id: Idc5100eaf09033998c155572d44c6c0ad0ba9ef6 Reviewed-by: Thiago Macieira --- src/corelib/doc/src/threads.qdoc | 118 ++++++++++++++++++++++++++++----------- 1 file changed, 86 insertions(+), 32 deletions(-) diff --git a/src/corelib/doc/src/threads.qdoc b/src/corelib/doc/src/threads.qdoc index 8962dceb01..890fd9f6ff 100644 --- a/src/corelib/doc/src/threads.qdoc +++ b/src/corelib/doc/src/threads.qdoc @@ -123,7 +123,7 @@ \nextpage Synchronizing Threads Qt offers many classes and functions for working with threads. Below are - three different approaches that Qt programmers can use to implement + four different approaches that Qt programmers can use to implement multithreaded applications. @@ -163,19 +163,47 @@ \section1 Qt Concurrent: Using a High-level API The \l{Qt Concurrent} module provides high-level functions that deal with some - common parallel computation patterns: map, filter, and reduce. Unlike QThread - and QRunnable, these functions do not require the use of low-level threading - primitives such as mutexes or semaphores. \l {Qt Concurrent} will automatically - adjust the number of threads used according to the number of processor cores - available, so applications written today will continue to scale when deployed - later on a system with more cores. - - This module also provides the QtConcurrent::run() function, which can run - any function in a thread managed by the global QThreadPool. + common parallel computation patterns: map, filter, and reduce. Unlike using + QThread and QRunnable, these functions never require the use of \l{Synchronizing + Threads#Low-Level Synchronization Primitives}{low-level threading primitives} + such as mutexes or semaphores. Instead, they return a QFuture object which can + be used to retrieve the functions' results when they are ready. QFuture can + also be used to query computation progress and to pause/resume/cancel the + computation. For convenience, QFutureWatcher enables interactions with + \l{QFuture}s via signals and slots. + + \l{Qt Concurrent}'s map, filter and reduce algorithms automatically distribute + computation across all available processor cores, so applications written today + will continue to scale when deployed later on a system with more cores. + + This module also provides the QtConcurrent::run() function, which can run any + function in another thread. However, QtConcurrent::run() only supports a subset + of features available to the map, filter and reduce functions. The QFuture + can be used to retrieve the function's return value and to check if the thread + is running. However, a call to QtConcurrent::run() uses one thread only, cannot + be paused/resumed/canceled, and cannot be queried for progress. See the \l{Qt Concurrent} module documentation for details on the individual functions. + \section1 WorkerScript: Threading in QML + + The WorkerScript QML type lets JavaScript code run in parallel with the GUI + thread. + + Each WorkerScript instance can have one \c{.js} script attached to it. When + WorkerScript::sendMessage() is called, the script will run in a separate thread + (and a separate \l{QQmlContext}{QML context}). When the script finishes + running, it can send a reply back to the GUI thread which will invoke the + WorkerScript::onMessage() signal handler. + + Using a WorkerScript is similar to using a worker QObject that has been moved + to another thread. Data is transferred between threads via signals. + + See the WorkerScript documentation for details on how to implement the script, + and for a list of data types that can be passed between threads. + + \section1 Choosing an Appropriate Approach As demonstrated above, Qt provides different solutions for developing threaded @@ -187,52 +215,62 @@ \table \header - \li Feature/Characteristic + \li Feature \li QThread - \li QRunnable - \li Qt Concurrent\sup{*} + \li QRunnable and QThreadPool + \li QtConcurrent::run() + \li Qt Concurrent (Map, Filter, Reduce) + \li WorkerScript + \row + \li API + \li C++ + \li C++ + \li C++ + \li C++ + \li QML \row - \li Supports different thread priorities + \li Thread priority can be specified \li Yes + \li Yes + \li \li \li \row - \li Supports an event loop + \li Thread can run an event loop \li Yes \li \li + \li + \li \row - \li Supports transferring data to the thread using signals + \li Thread can receive data updates through signals \li Yes (received by a worker QObject) \li \li + \li + \li Yes (received by WorkerScript) \row - \li Supports controlling the thread using signals + \li Thread can be controlled using signals \li Yes (received by QThread) \li - \li Yes (received by QFutureWatcher) - \row - \li Supports thread reuse \li - \li Yes - \li Yes - \row - \li Task-oriented + \li Yes (received by QFutureWatcher) \li - \li Yes - \li Yes \row - \li High level API + \li Thread can be monitored through a QFuture \li \li + \li Partially \li Yes + \li \row - \li Supports pausing/resuming/canceling + \li Built-in ability to pause/resume/cancel + \li \li \li \li Yes + \li \endtable - \sup{\e{*Except QtConcurrent::run(), which is like QRunnable}} \section2 Example Use Cases @@ -244,7 +282,7 @@ \li Solution \row \li One call - \li Run a linear function within another thread, optionally with progress + \li Run a new linear function within another thread, optionally with progress updates during the run. \li Qt provides different solutions: \list @@ -256,6 +294,13 @@ \li Run the function using QtConcurrent::run(). Write to a \l{Synchronizing Threads}{thread-safe variable} to update progress. \endlist + \row + \li One call + \li Run an existing function within another thread and get its return value. + \li Run the function using QtConcurrent::run(). Have a QFutureWatcher emit + the \l{QFutureWatcher::}{finished()} signal when the function has + returned, and call QFutureWatcher::result() to get the function's return + value. \row \li One call \li Perform an operation on all items of a container, using all available @@ -263,8 +308,17 @@ \li Use Qt Concurrent's \l{QtConcurrent::}{filter()} function to select container elements, and the \l{QtConcurrent::}{map()} function to apply an operation to each element. To fold the output into a single result, - use \l{QtConcurrent::}{filterReduced()} and \l{QtConcurrent::}{mapReduced()} - instead. + use \l{QtConcurrent::}{filteredReduced()} and + \l{QtConcurrent::}{mappedReduced()} instead. + \row + \li One call/Permanent + \li Perfrom a long computation in a pure QML application, and update the GUI + when the results are ready. + \li Place the computation code in a \c{.js} script and attach it to a + WorkerScript instance. Call \l{WorkerScript::}{sendMessage()} to start the + computation in a new thread. Let the script call WorkerScript::sendMessage() + too, to pass the result back to the GUI thread. Handle the result in + \l{WorkerScript::}{onMessage} and update the GUI there. \row \li Permanent \li Have an object living in another thread that can perform different -- cgit v1.2.3 From 5c64847ba3d2a09a01baa197285b76904aadfbf8 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Thu, 10 Oct 2013 10:09:30 +0200 Subject: Android: Build autotest service against android-10 No need to default to yet another SDK here. This is a left-over from Necessitas, which supports versions down to android-4. Change-Id: I2e79be641288c14f92c205b30f2db6db793d783f Reviewed-by: Paul Olav Tvete --- tests/auto/android/runtests.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/android/runtests.pl b/tests/auto/android/runtests.pl index 55e1a224d8..365257aace 100755 --- a/tests/auto/android/runtests.pl +++ b/tests/auto/android/runtests.pl @@ -164,7 +164,7 @@ if ($output =~ m/.*\[ro.build.version.sdk\]: \[(\d+)\]/) sub reinstallQuadruplor { pushd($quadruplor_dir); - system("$android_sdk_dir/tools/android update project -p . -t android-4")==0 or die "Can't update project ...\n"; + system("$android_sdk_dir/tools/android update project -p . -t android-10")==0 or die "Can't update project ...\n"; system("$ant_tool uninstall clean debug install")==0 or die "Can't install Quadruplor\n"; system("$adb_tool $device_serial shell am start -n $intentName"); # create application folders waitForProcess($packageName,1,10); -- cgit v1.2.3 From 4be5d5820361f1482c63c3eeb7eaac5d61a2b211 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Thu, 10 Oct 2013 14:49:47 +0200 Subject: Android: Make it possible to pass arguments via intent extras Needed for autotest script, so that we can pass command line arguments to Qt Test. This can now be done by: % adb shell am start \ -e applicationArguments "argument1 argument2" \ Change-Id: I772209f66da055c6a0b01b709f36e33fdb5c2ed6 Reviewed-by: Paul Olav Tvete Reviewed-by: BogDan Vatra --- .../java/src/org/qtproject/qt5/android/bindings/QtActivity.java | 8 ++++++++ src/plugins/platforms/android/src/androidjnimain.cpp | 7 ++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java b/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java index 83ed1582bf..9c7b57a4f5 100644 --- a/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java +++ b/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java @@ -489,6 +489,14 @@ public class QtActivity extends Activity + "\tQML2_IMPORT_PATH=" + localPrefix + "/qml" + "\tQML_IMPORT_PATH=" + localPrefix + "/imports" + "\tQT_PLUGIN_PATH=" + localPrefix + "/plugins"); + + Intent intent = getIntent(); + if (intent != null) { + String parameters = intent.getStringExtra("applicationArguments"); + if (parameters != null) + loaderParams.putString(APPLICATION_PARAMETERS_KEY, parameters.replace(' ', '\t')); + } + loadApplication(loaderParams); return; } diff --git a/src/plugins/platforms/android/src/androidjnimain.cpp b/src/plugins/platforms/android/src/androidjnimain.cpp index b51c15c5d9..5c9ca798a8 100644 --- a/src/plugins/platforms/android/src/androidjnimain.cpp +++ b/src/plugins/platforms/android/src/androidjnimain.cpp @@ -419,14 +419,11 @@ static jboolean startQtAndroidPlugin(JNIEnv* /*env*/, jobject /*object*//*, jobj static void *startMainMethod(void */*data*/) { - char const **params; - params = static_cast(malloc(m_applicationParams.length() * sizeof(char *))); + QVarLengthArray params(m_applicationParams.size()); for (int i = 0; i < m_applicationParams.size(); i++) params[i] = static_cast(m_applicationParams[i].constData()); - int ret = m_main(m_applicationParams.length(), const_cast(params)); - - free(params); + int ret = m_main(m_applicationParams.length(), const_cast(params.data())); Q_UNUSED(ret); if (m_mainLibraryHnd) { -- cgit v1.2.3 From f1b46a5ee0af99bf1425bbd0ab49830734ea7dbf Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Thu, 10 Oct 2013 15:16:33 +0200 Subject: Android: Add test script based on androiddeployqt There are a few problems with the Quadruplor setup in Qt 5. First of all, it doesn't work with modules, since it has a hard coded library dependency list. Second of all, it duplicates the application template, so changes need to also be duplicated. This often gets out of sync. Third of all, it duplicates a lot of deployment rules which are now contained in androiddeployqt. Task-number: QTBUG-33996 Change-Id: I0630a38aeba7d0075df8fae671abc311fc36de61 Reviewed-by: Paul Olav Tvete --- tests/auto/android/runtests_androiddeployqt.pl | 302 +++++++++++++++++++++++++ 1 file changed, 302 insertions(+) create mode 100755 tests/auto/android/runtests_androiddeployqt.pl diff --git a/tests/auto/android/runtests_androiddeployqt.pl b/tests/auto/android/runtests_androiddeployqt.pl new file mode 100755 index 0000000000..7940653176 --- /dev/null +++ b/tests/auto/android/runtests_androiddeployqt.pl @@ -0,0 +1,302 @@ +#!/usr/bin/perl -w +############################################################################# +## +## Copyright (C) 2012-2013 BogDan Vatra +## Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +## Contact: http://www.qt-project.org/legal +## +## This file is part of the test suite of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:LGPL$ +## 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 Digia. For licensing terms and +## conditions see http://qt.digia.com/licensing. For further information +## use the contact form at http://qt.digia.com/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 as published by the Free Software +## Foundation and appearing in the file LICENSE.LGPL included in the +## packaging of this file. Please review the following information to +## ensure the GNU Lesser General Public License version 2.1 requirements +## will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +## +## In addition, as a special exception, Digia gives you certain additional +## rights. These rights are described in the Digia Qt LGPL Exception +## version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 3.0 as published by the Free Software +## Foundation and appearing in the file LICENSE.GPL included in the +## packaging of this file. Please review the following information to +## ensure the GNU General Public License version 3.0 requirements will be +## met: http://www.gnu.org/copyleft/gpl.html. +## +## +## $QT_END_LICENSE$ +## +############################################################################# + +use Cwd; +use Cwd 'abs_path'; +use File::Basename; +use File::Temp 'tempdir'; +use File::Path 'remove_tree'; +use Getopt::Long; +use Pod::Usage; + +### default options +my @stack = cwd; +my $device_serial=""; # "-s device_serial"; +my $deployqt_device_serial=""; # "-device device_serial"; +my $className="org.qtproject.qt5.android.bindings.QtActivity"; +my $jobs = 4; +my $testsubset = ""; +my $man = 0; +my $help = 0; +my $make_clean = 0; +my $time_out=400; +my $android_sdk_dir = "$ENV{'ANDROID_SDK_ROOT'}"; +my $android_ndk_dir = "$ENV{'ANDROID_NDK_ROOT'}"; +my $ant_tool = `which ant`; +chomp $ant_tool; +my $strip_tool=""; +my $readelf_tool=""; +GetOptions('h|help' => \$help + , man => \$man + , 's|serial=s' => \$device_serial + , 't|test=s' => \$testsubset + , 'c|clean' => \$make_clean + , 'j|jobs=i' => \$jobs + , 'sdk=s' => \$android_sdk_dir + , 'ndk=s' => \$android_ndk_dir + , 'ant=s' => \$ant_tool + , 'strip=s' => \$strip_tool + , 'readelf=s' => \$readelf_tool + , 'testcase=s' => \$testcase + ) or pod2usage(2); +pod2usage(1) if $help; +pod2usage(-verbose => 2) if $man; + +my $adb_tool="$android_sdk_dir/platform-tools/adb"; +system("$adb_tool devices") == 0 or die "No device found, please plug/start at least one device/emulator\n"; # make sure we have at least on device attached + +$device_serial = "-s $device_serial" if ($device_serial); +$deployqt_device_serial = "--device $device_serial" if ($device_serial); +$testsubset="/$testsubset" if ($testsubset); + +$strip_tool="$android_ndk_dir/toolchains/arm-linux-androideabi-4.7/prebuilt/linux-x86/bin/arm-linux-androideabi-strip" unless($strip_tool); +$readelf_tool="$android_ndk_dir/toolchains/arm-linux-androideabi-4.7/prebuilt/linux-x86/bin/arm-linux-androideabi-readelf" unless($readelf_tool); +$readelf_tool="$readelf_tool -d -w "; + +sub dir +{ +# print "@stack\n"; +} + +sub pushd ($) +{ + unless ( chdir $_[0] ) + { + warn "Error: $!\n"; + return; + } + unshift @stack, cwd; + dir; +} + +sub popd () +{ + @stack > 1 and shift @stack; + chdir $stack[0]; + dir; +} + + +sub waitForProcess +{ + my $process=shift; + my $action=shift; + my $timeout=shift; + my $sleepPeriod=shift; + $sleepPeriod=1 if !defined($sleepPeriod); + print "Waiting for $process ".$timeout*$sleepPeriod." seconds to"; + print $action?" start...\n":" die...\n"; + while ($timeout--) + { + my $output = `$adb_tool $device_serial shell ps 2>&1`; # get current processes + #FIXME check why $output is not matching m/.*S $process\n/ or m/.*S $process$/ (eol) + my $res=($output =~ m/.*S $process/)?1:0; # check the procress + if ($action == $res) + { + print "... succeed\n"; + return 1; + } + sleep($sleepPeriod); + print "timeount in ".$timeout*$sleepPeriod." seconds\n" + } + print "... failed\n"; + return 0; +} + +my $src_dir_qt=abs_path(dirname($0)."/../../.."); +my $quadruplor_dir="$src_dir_qt/tests/auto/android"; +my $qmake_path="$src_dir_qt/bin/qmake"; +my $tests_dir="$src_dir_qt/tests$testsubset"; +my $temp_dir=tempdir(CLEANUP => 1); +my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); +my $output_dir=$stack[0]."/".(1900+$year)."-$mon-$mday-$hour:$min"; +mkdir($output_dir); +my $sdk_api=0; +my $output = `$adb_tool $device_serial shell getprop`; # get device properties +if ($output =~ m/.*\[ro.build.version.sdk\]: \[(\d+)\]/) +{ + $sdk_api=int($1); + $sdk_api=5 if ($sdk_api>5 && $sdk_api<8); + $sdk_api=9 if ($sdk_api>9); +} + +sub startTest +{ + my $testName = shift; + my $packageName = "org.qtproject.example.tst_$testName"; + my $intentName = "$packageName/org.qtproject.qt5.android.bindings.QtActivity"; + my $output_file = shift; + + system("$adb_tool $device_serial shell am start -e applicationArguments \"-o /data/data/$packageName/output.xml\" -n $intentName"); # start intent + #wait to start (if it has not started and quit already) + waitForProcess($packageName,1,10); + + #wait to stop + unless(waitForProcess($packageName,0,$time_out,5)) + { + killProcess($packageName); + return 1; + } + system("$adb_tool $device_serial pull /data/data/$packageName/output.xml $output_dir/$output_file"); + return 1; +} + +########### build qt tests and benchmarks ########### +pushd($tests_dir); +print "Building $tests_dir \n"; +system("make distclean") if ($make_clean); +system("$qmake_path -r") == 0 or die "Can't run qmake\n"; #exec qmake +system("make -j$jobs") == 0 or warn "Can't build all tests\n"; #exec make + +my $testsFiles = ""; +if ($testcase) { + $testsFiles=`find . -name libtst_$testcase.so`; # only tests +} else { + $testsFiles=`find . -name libtst_*.so`; # only tests +} + +foreach (split("\n",$testsFiles)) +{ + chomp; #remove white spaces + pushd(abs_path(dirname($_))); # cd to application dir + system("make INSTALL_ROOT=$temp_dir install"); # install the application to temp dir + my $application=basename(cwd); + system("androiddeployqt --install $deployqt_device_serial --output $temp_dir --deployment debug --verbose --input android-libtst_$application.so-deployment-settings.json"); + my $output_name=dirname($_); + $output_name =~ s/\.//; # remove first "." character + $output_name =~ s/\///; # remove first "/" character + $output_name =~ s/\//_/g; # replace all "/" with "_" + $output_name=$application unless($output_name); + $time_out=5*60/5; # 5 minutes time out for a normal test + + $applicationLibrary = `find $temp_dir -name libtst_bench_$application.so`; + + if ($applicationLibrary) + { + $time_out=5*60/5; # 10 minutes for a benchmark + $application = "bench_$application"; + } + else + { + $applicationLibrary = `find $temp_dir -name libtst_$application.so`; + } + + if (!$applicationLibrary) + { + print "Can't find application binary libtst_$application.so in $temp_dir!\n"; + } + else + { + startTest($application, "$output_name.xml") or warn "Can't run $application ...\n"; + } + + popd(); + remove_tree( $temp_dir, {keep_root => 1} ); +} +popd(); + +__END__ + +=head1 NAME + +Script to run all qt tests/benchmarks to an android device/emulator + +=head1 SYNOPSIS + +runtests.pl [options] + +=head1 OPTIONS + +=over 8 + +=item B<-s --serial = serial> + +Device serial number. May be empty if only one device is attached. + +=item B<-t --test = test_subset> + +Tests subset (e.g. benchmarks, auto, auto/qbuffer, etc.). + +=item B<-c --clean> + +Clean tests before building them. + +=item B<-j --jobs = number> + +Make jobs when building tests. + +=item B<--sdk = sdk_path> + +Android SDK path. + +=item B<--ndk = ndk_path> + +Android NDK path. + +=item B<--ant = ant_tool_path> + +Ant tool path. + +=item B<--strip = strip_tool_path> + +Android strip tool path, used to deploy qt libs. + +=item B<--readelf = readelf_tool_path> + +Android readelf tool path, used to check if a test application uses qt OpenGL. + +=item B<-h --help> + +Print a brief help message and exits. + +=item B<--man> + +Prints the manual page and exits. + +=back + +=head1 DESCRIPTION + +B will run all qt tests/benchmarks to an android device/emulator. + +=cut -- cgit v1.2.3 From d4d96c375df5e697f878b15548c1abff7e35ff08 Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Mon, 7 Oct 2013 15:03:37 +0200 Subject: Android: don't set autorepeat to true by default When we don't know if a key event is caused by autorepeat, then the safest assumption is that it is not. Task-number: QTBUG-30793 Change-Id: Iea6aba164e299f0f2c772547b45df6a49639b7e9 Reviewed-by: Eskil Abrahamsen Blomfeldt Reviewed-by: BogDan Vatra --- src/plugins/platforms/android/src/androidjniinput.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/android/src/androidjniinput.cpp b/src/plugins/platforms/android/src/androidjniinput.cpp index bd40f736e0..1e8a847159 100644 --- a/src/plugins/platforms/android/src/androidjniinput.cpp +++ b/src/plugins/platforms/android/src/androidjniinput.cpp @@ -485,7 +485,7 @@ namespace QtAndroidInput mapAndroidKey(key), modifiers, QChar(unicode), - true); + false); } static void keyUp(JNIEnv */*env*/, jobject /*thiz*/, jint key, jint unicode, jint modifier) @@ -505,7 +505,7 @@ namespace QtAndroidInput mapAndroidKey(key), modifiers, QChar(unicode), - true); + false); } -- cgit v1.2.3 From 1f01ac832346fb217e7c07452673cd5f66cf4835 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Mon, 14 Oct 2013 13:26:03 +0200 Subject: Restore handling of bullets for lists with a font size of > 36 pixels This patch partially reverts ad443dfb1d8e9096c4913686aa2ed0bc9b3f5de7, the test that was added is still there as it can be used to compare against Chrome and to check that indenting works correctly. The original behavior of clipping the bullets is correct because the specified indent is where the text itself should be positioned, the bullet uses the available space to the side of it. This is how other web browsers handle the same situation. Change-Id: I63440e037d8efec356459c09228ef4817ccb9cb6 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/text/qtextdocumentlayout.cpp | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/gui/text/qtextdocumentlayout.cpp b/src/gui/text/qtextdocumentlayout.cpp index 6156f56ae1..313700429c 100644 --- a/src/gui/text/qtextdocumentlayout.cpp +++ b/src/gui/text/qtextdocumentlayout.cpp @@ -1427,19 +1427,6 @@ void QTextDocumentLayoutPrivate::drawListItem(const QPointF &offset, QPainter *p xoff = -xoff - size.width(); r.translate( xoff, (fontMetrics.height() / 2) - (size.height() / 2)); - // Prevent clipping the left side of the list decorator (on left to - // right layouts) and clipping the right side of the list - // decorator (on right to left layouts). - if ((r.left() < 0) && (dir == Qt::LeftToRight)) { - int horizontalOffset = -r.left(); - r.translate(horizontalOffset, 0); - layout->setPosition(layout->position() + QPointF(horizontalOffset, 0)); - } else if ((r.right() > document->pageSize().width()) && (dir == Qt::RightToLeft)) { - int horizontalOffset = r.right() - document->pageSize().width(); - r.translate(-horizontalOffset, 0); - layout->setPosition(layout->position() - QPointF(horizontalOffset, 0)); - } - painter->save(); painter->setRenderHint(QPainter::Antialiasing); -- cgit v1.2.3 From 5f47ce0951214aad2eee46f6936b5ee513ed0fed Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Mon, 14 Oct 2013 16:49:10 +0300 Subject: Remove unused include Change-Id: I77bd22b3e0314686450343c5a52914d7f97298d3 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/plugins/platforms/android/src/qandroidplatformintegration.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/plugins/platforms/android/src/qandroidplatformintegration.cpp b/src/plugins/platforms/android/src/qandroidplatformintegration.cpp index 9ce382bd53..a3db421de9 100644 --- a/src/plugins/platforms/android/src/qandroidplatformintegration.cpp +++ b/src/plugins/platforms/android/src/qandroidplatformintegration.cpp @@ -42,7 +42,6 @@ #include "qandroidplatformintegration.h" #include "qabstracteventdispatcher.h" #include "androidjnimain.h" -#include #include #include #include -- cgit v1.2.3 From e29b35024e3adf3b58770573cb512395bc5fe176 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Tue, 15 Oct 2013 16:32:26 +0200 Subject: Don't test DLLDESTDIR when calculating dll location. The DLLDESTDIR is not related to the install location and is not populated for prefix_build configurations. That resulted in the CMake files attempting to find the dlls in the lib/ directory instead of the bin/ directory. Change-Id: Iec6a7c9b6dd656278b70ab128f3df9e8c45bbe4a Reviewed-by: Oswald Buddenhagen --- mkspecs/features/create_cmake.prf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkspecs/features/create_cmake.prf b/mkspecs/features/create_cmake.prf index d799e20c46..5abca8940b 100644 --- a/mkspecs/features/create_cmake.prf +++ b/mkspecs/features/create_cmake.prf @@ -68,7 +68,7 @@ contains(CMAKE_PLUGIN_DIR, "^\\.\\./.*") { CMAKE_PLUGIN_DIR_IS_ABSOLUTE = True } -!isEmpty(DLLDESTDIR):!static:!staticlib { +win32:!wince:!static:!staticlib { CMAKE_DLL_DIR = $$cmakeRelativePath($$[QT_INSTALL_BINS], $$[QT_INSTALL_PREFIX]) contains(CMAKE_DLL_DIR, "^\\.\\./.*") { CMAKE_DLL_DIR = $$[QT_INSTALL_BINS]/ -- cgit v1.2.3 From 786b278f91aa4d5f1ff8fa10555bf6c8741c96a0 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Tue, 15 Oct 2013 23:18:44 +0200 Subject: Generate source includes in a separate file, if needed. The source includes shouldn't be used by installations, so don't install the extra file, but only use it if the package is used from the build-dir. Task-number: QTBUG-33970 Change-Id: I08f91b8a716e935cb04d1233d44cf5c092e240ce Reviewed-by: Oswald Buddenhagen Reviewed-by: Stephen Kelly --- mkspecs/features/create_cmake.prf | 9 +++++++++ mkspecs/features/data/cmake/ExtraSourceIncludes.cmake.in | 7 +++++++ mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in | 7 +------ 3 files changed, 17 insertions(+), 6 deletions(-) create mode 100644 mkspecs/features/data/cmake/ExtraSourceIncludes.cmake.in diff --git a/mkspecs/features/create_cmake.prf b/mkspecs/features/create_cmake.prf index 5abca8940b..b1422f25e2 100644 --- a/mkspecs/features/create_cmake.prf +++ b/mkspecs/features/create_cmake.prf @@ -35,6 +35,15 @@ split_incpath { CMAKE_SOURCE_PRIVATE_INCLUDES = \ $$cmakeTargetPath($$QT_MODULE_INCLUDE_BASE/Qt$${CMAKE_MODULE_NAME}/$$eval(QT.$${MODULE}.VERSION)) \ $$cmakeTargetPath($$QT_MODULE_INCLUDE_BASE/Qt$${CMAKE_MODULE_NAME}/$$eval(QT.$${MODULE}.VERSION)/Qt$${CMAKE_MODULE_NAME}) + + cmake_extra_source_includes.input = $$PWD/data/cmake/ExtraSourceIncludes.cmake.in + cmake_extra_source_includes.output = $$DESTDIR/cmake/Qt5$${CMAKE_MODULE_NAME}/ExtraSourceIncludes.cmake + + !build_pass:QMAKE_SUBSTITUTES += \ + cmake_extra_source_includes + + cmake_qt5_module_files.files = \ + $$cmake_extra_source_includes.output } CMAKE_INCLUDE_DIR = $$cmakeRelativePath($$[QT_INSTALL_HEADERS], $$[QT_INSTALL_PREFIX]) diff --git a/mkspecs/features/data/cmake/ExtraSourceIncludes.cmake.in b/mkspecs/features/data/cmake/ExtraSourceIncludes.cmake.in new file mode 100644 index 0000000000..ec8075f3f7 --- /dev/null +++ b/mkspecs/features/data/cmake/ExtraSourceIncludes.cmake.in @@ -0,0 +1,7 @@ + +list(APPEND _Qt5$${CMAKE_MODULE_NAME}_OWN_INCLUDE_DIRS + $$CMAKE_SOURCE_INCLUDES +) +set(Qt5$${CMAKE_MODULE_NAME}_PRIVATE_INCLUDE_DIRS + $$CMAKE_SOURCE_PRIVATE_INCLUDES +) diff --git a/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in b/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in index 245c0ae768..0cdaafee7f 100644 --- a/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in +++ b/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in @@ -121,12 +121,7 @@ if (NOT TARGET Qt5::$${CMAKE_MODULE_NAME}) !!ENDIF !!ENDIF !!IF !isEmpty(CMAKE_ADD_SOURCE_INCLUDE_DIRS) - list(APPEND _Qt5$${CMAKE_MODULE_NAME}_OWN_INCLUDE_DIRS - $$CMAKE_SOURCE_INCLUDES - ) - set(Qt5$${CMAKE_MODULE_NAME}_PRIVATE_INCLUDE_DIRS - $$CMAKE_SOURCE_PRIVATE_INCLUDES - ) + include(\"${CMAKE_CURRENT_LIST_DIR}/ExtraSourceIncludes.cmake\" OPTIONAL) !!ENDIF !!ELSE set(_Qt5$${CMAKE_MODULE_NAME}_OWN_INCLUDE_DIRS) -- cgit v1.2.3 From b257f33b97251a3e266e04574c09ebebdae7ac8f Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Wed, 16 Oct 2013 14:45:45 +0200 Subject: Output prefix for tools on x86 When building for x86, the prefix for the tools is not equal to the prefix for the toolchain directory, so we need a separate option for this. Task-number: QTBUG-34110 Change-Id: Iefe8c37892eb6c31fc8762bfb7bc7c6c23cd8b1e Reviewed-by: BogDan Vatra --- mkspecs/features/android/android_deployment_settings.prf | 1 + 1 file changed, 1 insertion(+) diff --git a/mkspecs/features/android/android_deployment_settings.prf b/mkspecs/features/android/android_deployment_settings.prf index eb18d38a7f..9ac826e860 100644 --- a/mkspecs/features/android/android_deployment_settings.prf +++ b/mkspecs/features/android/android_deployment_settings.prf @@ -25,6 +25,7 @@ contains(TEMPLATE, ".*app"):!build_pass:!android-no-sdk { else: NDK_TOOLCHAIN_PREFIX = arm-linux-androideabi } FILE_CONTENT += " \"toolchain-prefix\": $$emitString($$NDK_TOOLCHAIN_PREFIX)," + FILE_CONTENT += " \"tool-prefix\": $$emitString($$NDK_TOOLS_PREFIX)," NDK_TOOLCHAIN_VERSION = $$(ANDROID_NDK_TOOLCHAIN_VERSION) isEmpty(NDK_TOOLCHAIN_VERSION): NDK_TOOLCHAIN_VERSION = $$DEFAULT_ANDROID_NDK_TOOLCHAIN_VERSION -- cgit v1.2.3 From 5b88f7b0ac1ac16ab7cc12242c675c6eb4413ff9 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Wed, 16 Oct 2013 12:51:19 +0200 Subject: Use the cmakeTargetPaths function to process multiple paths. Change-Id: I2e874af4f5bf22a3028b7099c39436c400136386 Reviewed-by: Oswald Buddenhagen Reviewed-by: Stephen Kelly --- mkspecs/features/create_cmake.prf | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/mkspecs/features/create_cmake.prf b/mkspecs/features/create_cmake.prf index b1422f25e2..4643c3915c 100644 --- a/mkspecs/features/create_cmake.prf +++ b/mkspecs/features/create_cmake.prf @@ -30,11 +30,10 @@ split_incpath { CMAKE_ADD_SOURCE_INCLUDE_DIRS = true CMAKE_NO_PRIVATE_INCLUDES = true # Don't add private includes in the build dir which don't exist CMAKE_SOURCE_INCLUDES = \ - $$cmakeTargetPath($$QT_MODULE_INCLUDE_BASE) \ - $$cmakeTargetPath($$QT_MODULE_INCLUDE_BASE/Qt$${CMAKE_MODULE_NAME}) + $$cmakeTargetPaths($$QT_MODULE_INCLUDE_BASE $$QT_MODULE_INCLUDE_BASE/Qt$${CMAKE_MODULE_NAME}) CMAKE_SOURCE_PRIVATE_INCLUDES = \ - $$cmakeTargetPath($$QT_MODULE_INCLUDE_BASE/Qt$${CMAKE_MODULE_NAME}/$$eval(QT.$${MODULE}.VERSION)) \ - $$cmakeTargetPath($$QT_MODULE_INCLUDE_BASE/Qt$${CMAKE_MODULE_NAME}/$$eval(QT.$${MODULE}.VERSION)/Qt$${CMAKE_MODULE_NAME}) + $$cmakeTargetPaths($$QT_MODULE_INCLUDE_BASE/Qt$${CMAKE_MODULE_NAME}/$$eval(QT.$${MODULE}.VERSION) \ + $$QT_MODULE_INCLUDE_BASE/Qt$${CMAKE_MODULE_NAME}/$$eval(QT.$${MODULE}.VERSION)/Qt$${CMAKE_MODULE_NAME}) cmake_extra_source_includes.input = $$PWD/data/cmake/ExtraSourceIncludes.cmake.in cmake_extra_source_includes.output = $$DESTDIR/cmake/Qt5$${CMAKE_MODULE_NAME}/ExtraSourceIncludes.cmake -- cgit v1.2.3 From 42f0a4f2c91800830021ac974678e46d52f23ae7 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Mon, 30 Sep 2013 16:40:55 +0200 Subject: Cocoa: Deliver key event to top-level QWidgetWindow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Having several QWidgetWindow in our hierarchy translates as as many NSViews. Clicking will make the NSView under the mouse cursor key, meaning it will receive all the Cocoa key events. In order to make sure the QWidgets hierarchy sees the key event "as usual," we climb the QWindow hierarchy in search for the top-level QWidgetWindow. (Something similar is already being done in -[QNSView becomeFirstResponder]). Task-number: QTBUG-32914 Change-Id: Idc700309d202820de326d4e2990fad24d7b692ae Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qnsview.mm | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 8813a934bf..f471a61aa0 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -208,6 +208,22 @@ static QTouchDevice *touchDevice = 0; if ([self window]) [[NSNotificationCenter defaultCenter] removeObserver:self name:nil object:[self window]]; } + +- (QWindow *)topLevelWindow +{ + QWindow *focusWindow = m_window; + + // For widgets we need to do a bit of trickery as the window + // to activate is the window of the top-level widget. + if (m_window->metaObject()->className() == QStringLiteral("QWidgetWindow")) { + while (focusWindow->parent()) { + focusWindow = focusWindow->parent(); + } + } + + return focusWindow; +} + - (void)updateGeometry { QRect geometry; @@ -457,16 +473,7 @@ static QTouchDevice *touchDevice = 0; { if (m_window->flags() & Qt::WindowTransparentForInput) return NO; - QWindow *focusWindow = m_window; - - // For widgets we need to do a bit of trickery as the window - // to activate is the window of the top-level widget. - if (m_window->metaObject()->className() == QStringLiteral("QWidgetWindow")) { - while (focusWindow->parent()) { - focusWindow = focusWindow->parent(); - } - } - QWindowSystemInterface::handleWindowActivated(focusWindow); + QWindowSystemInterface::handleWindowActivated([self topLevelWindow]); return YES; } @@ -1124,10 +1131,12 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent) if (ch.unicode() < 0xf700 || ch.unicode() > 0xf8ff) text = QCFString::toQString(characters); + QWindow *focusWindow = [self topLevelWindow]; + if (eventType == QEvent::KeyPress) { if (m_composingText.isEmpty()) - m_sendKeyEvent = !QWindowSystemInterface::tryHandleShortcutEvent(m_window, timestamp, keyCode, modifiers, text); + m_sendKeyEvent = !QWindowSystemInterface::tryHandleShortcutEvent(focusWindow, timestamp, keyCode, modifiers, text); QObject *fo = QGuiApplication::focusObject(); if (m_sendKeyEvent && fo) { @@ -1144,7 +1153,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent) } if (m_sendKeyEvent && m_composingText.isEmpty()) - QWindowSystemInterface::handleExtendedKeyEvent(m_window, timestamp, QEvent::Type(eventType), keyCode, modifiers, + QWindowSystemInterface::handleExtendedKeyEvent(focusWindow, timestamp, QEvent::Type(eventType), keyCode, modifiers, nativeScanCode, nativeVirtualKey, nativeModifiers, text, [nsevent isARepeat]); m_sendKeyEvent = false; -- cgit v1.2.3 From 8f0654ceb878b6c8a08c7f5b790027c26e007c13 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Mon, 14 Oct 2013 14:08:41 +0200 Subject: Give an example how to configure categorized logging Change-Id: I178bb6e75fba246932b318c2c0c5afd243575a92 Reviewed-by: Jerome Pasion Reviewed-by: hjk --- src/corelib/doc/snippets/qloggingcategory/main.cpp | 44 ++++++++++++----- src/corelib/io/qloggingcategory.cpp | 56 ++++++++++++++-------- 2 files changed, 67 insertions(+), 33 deletions(-) diff --git a/src/corelib/doc/snippets/qloggingcategory/main.cpp b/src/corelib/doc/snippets/qloggingcategory/main.cpp index 27d64e8253..c1dad7f43a 100644 --- a/src/corelib/doc/snippets/qloggingcategory/main.cpp +++ b/src/corelib/doc/snippets/qloggingcategory/main.cpp @@ -67,24 +67,45 @@ QList usbEntries() { return entries; } -void main(int argc, char *argv[]) +//![20] +void myCategoryFilter(QLoggingCategory *); +//![20] + +//![21] +QLoggingCategory::CategoryFilter oldCategoryFilter; + +void myCategoryFilter(QLoggingCategory *category) +{ + // configure qt.driver.usb category here, otherwise forward to to default filter. + if (qstrcmp(category->categoryName(), "qt.driver.usb") == 0) + category->setEnabled(QtDebugMsg, true); + else + oldCategoryFilter(category); +} +//![21] + +int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); //![2] - // don't run the expensive code if the string won't print - if (QT_DRIVER_USB().isDebugEnabled()) { - QStringList items; - foreach (const UsbEntry &entry, usbEntries()) - items << QString("%1 (%2)").arg(entry.id, entry.classtype); - qCDebug(QT_DRIVER_USB) << "devices: " << items; - } + QLoggingCategory::setFilterRules(QStringLiteral("qt.driver.usb.debug=true")); //![2] +//![22] + +// ... +oldCategoryFilter = QLoggingCategory::installFilter(myCategoryFilter); +//![22] + +//![3] + qSetMessagePattern("%{category} %{message}"); //![3] + +//![4] // usbEntries() will only be called if QT_DRIVER_USB category is enabled qCDebug(QT_DRIVER_USB) << "devices: " << usbEntries(); -//![3] +//![4] { //![10] @@ -106,8 +127,7 @@ void main(int argc, char *argv[]) qCCritical(category) << "a critical message"; //![12] } + + return 0; } -//![20] -void myCategoryFilter(QLoggingCategory *); -//![20] diff --git a/src/corelib/io/qloggingcategory.cpp b/src/corelib/io/qloggingcategory.cpp index 2ef392c209..e3151b61cc 100644 --- a/src/corelib/io/qloggingcategory.cpp +++ b/src/corelib/io/qloggingcategory.cpp @@ -71,30 +71,36 @@ Q_GLOBAL_STATIC_WITH_ARGS(QLoggingCategory, qtDefaultCategory, \section1 Checking category configuration - QLoggingCategory provides a generic \l isEnabled() and message - type dependent \l isDebugEnabled(), \l isWarningEnabled(), - \l isCriticalEnabled() and \l isTraceEnabled() - methods for checking whether the current category is enabled. + QLoggingCategory provides \l isDebugEnabled(), \l isWarningEnabled(), + \l isCriticalEnabled(), \l isTraceEnabled(), as well as \l isEnabled() + to check whether messages for the given message type should be logged. \note The qCDebug(), qCWarning(), qCCritical(), qCTrace() and qCTraceGuard() macros prevent arguments from being evaluated if the respective message types are not enabled for the category, so explicit checking is not needed: - \snippet qloggingcategory/main.cpp 3 + \snippet qloggingcategory/main.cpp 4 - \section1 Default configuration + \section1 Default category configuration In the default configuration \l isWarningEnabled() and \l isCriticalEnabled() - will return \c true. By default, \l isDebugEnabled() will return \c true only + will return \c true. \l isDebugEnabled() will return \c true only for the \c "default" category. - \section1 Changing configuration + \section1 Changing the configuration of a category + + Use either \l setFilterRules() or \l installFilter() to + configure categories, for example + + \snippet qloggingcategory/main.cpp 2 + + \section1 Printing the category + + Use the \c %{category} place holder to print the category in the default + message handler: - The default configuration can be changed by calling \l setEnabled(). However, - this only affects the current category object, not e.g. another object for the - same category name. Use either \l setFilterRules() or \l installFilter() to - configure categories globally. + \snippet qloggingcategory/main.cpp 3 */ typedef QVector Tracers; @@ -215,14 +221,12 @@ bool QLoggingCategory::isEnabled(QtMsgType msgtype) const /*! Changes the message type \a type for the category to \a enable. - Changes only affect the current QLoggingCategory object, and won't - change e.g. the settings of another objects for the same category name. + \note Changes only affect the current QLoggingCategory object, and won't + change the settings of other objects for the same category name. + Use either \l setFilterRules() or \l installFilter() to change the + configuration globally. \note \c QtFatalMsg cannot be changed. It will always return \c true. - - Example: - - \snippet qtracer/ftracer.cpp 5 */ void QLoggingCategory::setEnabled(QtMsgType type, bool enable) { @@ -279,6 +283,12 @@ QLoggingCategory *QLoggingCategory::defaultCategory() filter is free to change the respective category configuration with \l setEnabled(). + The filter might be called concurrently from different threads, and + therefore has to be reentrant. + + Example: + \snippet qloggingcategory/main.cpp 21 + An alternative way of configuring the default filter is via \l setFilterRules(). */ @@ -288,7 +298,6 @@ QLoggingCategory::installFilter(QLoggingCategory::CategoryFilter filter) return QLoggingRegistry::instance()->installFilter(filter); } - /*! Configures which categories and message types should be enabled through a a set of \a rules. @@ -303,8 +312,13 @@ QLoggingCategory::installFilter(QLoggingCategory::CategoryFilter filter) wildcard symbol at the start and/or the end. The optional \c must be either \c debug, \c warning, \c critical, or \c trace. - The rules might be ignored if a custom category filter is installed with - \l installFilter(). + Example: + + \snippet qloggingcategory/main.cpp 2 + + \note The rules might be ignored if a custom category filter is installed + with \l installFilter(). + */ void QLoggingCategory::setFilterRules(const QString &rules) { -- cgit v1.2.3 From 5d4eda78332e931394042948f9436586b221c83f Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 7 Oct 2013 20:07:07 +0200 Subject: use pkg-config supplied CFLAGS when building with EGL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit e.g., -DEGL_API_FB=1 is required for freescale's gpu-viv-bin-imx6 fb driver. Initial-patch-by: Fatih Aşıcı Change-Id: I8c8cd60591605e0bc33fcf9de3bfb6ea0d86a570 Reviewed-by: Thiago Macieira --- configure | 1 + mkspecs/features/egl.prf | 2 ++ 2 files changed, 3 insertions(+) diff --git a/configure b/configure index adcc64bba2..5271e6ba1a 100755 --- a/configure +++ b/configure @@ -5501,6 +5501,7 @@ elif [ "$CFG_EGL" != "no" ]; then QMAKE_CFLAGS_EGL=`$PKG_CONFIG --cflags egl 2>/dev/null` QMakeVar set QMAKE_INCDIR_EGL "$QMAKE_INCDIR_EGL" QMakeVar set QMAKE_LIBS_EGL "$QMAKE_LIBS_EGL" + QMakeVar set QMAKE_CFLAGS_EGL "`echo " $QMAKE_CFLAGS_EGL " | sed -e 's, -I[^ ]* , ,g;s,^ ,,;s, $,,'`" fi # detect EGL support if compileTest qpa/egl "EGL" $QMAKE_CFLAGS_EGL $QMAKE_LIBS_EGL; then CFG_EGL=yes diff --git a/mkspecs/features/egl.prf b/mkspecs/features/egl.prf index 7e7d098236..3dd66bce53 100644 --- a/mkspecs/features/egl.prf +++ b/mkspecs/features/egl.prf @@ -14,6 +14,8 @@ wince*:contains(QT_CONFIG, opengles1) { } else { INCLUDEPATH += $$QMAKE_INCDIR_EGL LIBS_PRIVATE += $$QMAKE_LIBS_EGL + QMAKE_CFLAGS += $$QMAKE_CFLAGS_EGL + QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_EGL LIBS += $$QMAKE_LFLAGS_EGL for(p, QMAKE_LIBDIR_EGL) { exists($$p):LIBS_PRIVATE += -L$$p -- cgit v1.2.3 From 677825f0bad9ee8fb48edf3d4b18799d298767c5 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 8 Oct 2013 12:09:46 +0200 Subject: remove non-concurrent branch from concurrent example kinda stupid to have it ... Change-Id: Icb31c524e04f43b0fb966c5500e22dfd574f969f Reviewed-by: Thiago Macieira --- examples/qtconcurrent/map/main.cpp | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/examples/qtconcurrent/map/main.cpp b/examples/qtconcurrent/map/main.cpp index 199273b9a6..01595f0c2e 100644 --- a/examples/qtconcurrent/map/main.cpp +++ b/examples/qtconcurrent/map/main.cpp @@ -45,8 +45,6 @@ #include #include -#ifndef QT_NO_CONCURRENT - QImage scale(const QImage &image) { qDebug() << "Scaling image in thread" << QThread::currentThread(); @@ -70,23 +68,3 @@ int main(int argc, char *argv[]) return 0; } - -#else - -#include - -int main(int argc, char *argv[]) -{ - QApplication app(argc, argv); - QString text("Qt Concurrent is not yet supported on this platform"); - - QLabel *label = new QLabel(text); - label->setWordWrap(true); - - label->show(); - qDebug() << text; - - app.exec(); -} - -#endif -- cgit v1.2.3 From f14e2686949bf969c2b0da76816b71a7167089f9 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 8 Oct 2013 12:14:20 +0200 Subject: don't erroneously claim that gui support is needed Change-Id: Ia7b1f02cab9fa0fc9e487ca49d75e85ed0cfee9d Reviewed-by: Thiago Macieira --- examples/threads/semaphores/semaphores.cpp | 2 +- examples/threads/semaphores/semaphores.pro | 2 +- examples/threads/waitconditions/waitconditions.cpp | 2 +- examples/threads/waitconditions/waitconditions.pro | 2 +- .../animation/qparallelanimationgroup/qparallelanimationgroup.pro | 2 +- tests/auto/corelib/animation/qpauseanimation/qpauseanimation.pro | 2 +- .../auto/corelib/itemmodels/qabstractitemmodel/qabstractitemmodel.pro | 2 +- tests/auto/corelib/kernel/qmetaobjectbuilder/qmetaobjectbuilder.pro | 2 +- tests/auto/corelib/kernel/qpointer/qpointer.pro | 2 +- tests/auto/corelib/kernel/qsignalmapper/qsignalmapper.pro | 2 +- tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.pro | 1 + tests/auto/corelib/plugin/qfactoryloader/plugin2/plugin2.pro | 1 + .../plugin/quuid/testProcessUniqueness/testProcessUniqueness.pro | 1 + tests/auto/corelib/statemachine/qstatemachine/qstatemachine.pro | 2 +- tests/auto/corelib/tools/qbytedatabuffer/qbytedatabuffer.pro | 2 +- tests/auto/corelib/tools/qtimezone/qtimezone.pro | 2 +- tests/auto/dbus/qdbusmarshall/qdbusmarshall.pro | 2 +- tests/auto/other/modeltest/modeltest.cpp | 4 +--- 18 files changed, 18 insertions(+), 17 deletions(-) diff --git a/examples/threads/semaphores/semaphores.cpp b/examples/threads/semaphores/semaphores.cpp index f7b25238f6..fb7f1f2376 100644 --- a/examples/threads/semaphores/semaphores.cpp +++ b/examples/threads/semaphores/semaphores.cpp @@ -38,7 +38,7 @@ ** ****************************************************************************/ -#include +#include #include #include diff --git a/examples/threads/semaphores/semaphores.pro b/examples/threads/semaphores/semaphores.pro index 71bc5b3f35..7dfe7c3ba0 100644 --- a/examples/threads/semaphores/semaphores.pro +++ b/examples/threads/semaphores/semaphores.pro @@ -1,5 +1,5 @@ SOURCES += semaphores.cpp -QT = core gui +QT = core CONFIG -= app_bundle CONFIG += console diff --git a/examples/threads/waitconditions/waitconditions.cpp b/examples/threads/waitconditions/waitconditions.cpp index 3921334d42..6f5f56e737 100644 --- a/examples/threads/waitconditions/waitconditions.cpp +++ b/examples/threads/waitconditions/waitconditions.cpp @@ -38,7 +38,7 @@ ** ****************************************************************************/ -#include +#include #include #include diff --git a/examples/threads/waitconditions/waitconditions.pro b/examples/threads/waitconditions/waitconditions.pro index c8de0b3774..7f9491a0b1 100644 --- a/examples/threads/waitconditions/waitconditions.pro +++ b/examples/threads/waitconditions/waitconditions.pro @@ -1,4 +1,4 @@ -QT = core gui +QT = core CONFIG -= moc app_bundle CONFIG += console diff --git a/tests/auto/corelib/animation/qparallelanimationgroup/qparallelanimationgroup.pro b/tests/auto/corelib/animation/qparallelanimationgroup/qparallelanimationgroup.pro index 4383c44259..23343f27f5 100644 --- a/tests/auto/corelib/animation/qparallelanimationgroup/qparallelanimationgroup.pro +++ b/tests/auto/corelib/animation/qparallelanimationgroup/qparallelanimationgroup.pro @@ -1,6 +1,6 @@ CONFIG += testcase CONFIG += parallel_test TARGET = tst_qparallelanimationgroup -QT = core gui testlib +QT = core testlib SOURCES = tst_qparallelanimationgroup.cpp DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/corelib/animation/qpauseanimation/qpauseanimation.pro b/tests/auto/corelib/animation/qpauseanimation/qpauseanimation.pro index 812c98f8f0..4c2dd02951 100644 --- a/tests/auto/corelib/animation/qpauseanimation/qpauseanimation.pro +++ b/tests/auto/corelib/animation/qpauseanimation/qpauseanimation.pro @@ -1,6 +1,6 @@ CONFIG += testcase CONFIG += parallel_test TARGET = tst_qpauseanimation -QT = core-private gui-private testlib +QT = core-private testlib SOURCES = tst_qpauseanimation.cpp DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/corelib/itemmodels/qabstractitemmodel/qabstractitemmodel.pro b/tests/auto/corelib/itemmodels/qabstractitemmodel/qabstractitemmodel.pro index ef36f8d7fc..ef571de192 100644 --- a/tests/auto/corelib/itemmodels/qabstractitemmodel/qabstractitemmodel.pro +++ b/tests/auto/corelib/itemmodels/qabstractitemmodel/qabstractitemmodel.pro @@ -1,7 +1,7 @@ CONFIG += testcase CONFIG += parallel_test TARGET = tst_qabstractitemmodel -QT += testlib +QT = core testlib mtdir = ../../../other/modeltest INCLUDEPATH += $$PWD/$${mtdir} diff --git a/tests/auto/corelib/kernel/qmetaobjectbuilder/qmetaobjectbuilder.pro b/tests/auto/corelib/kernel/qmetaobjectbuilder/qmetaobjectbuilder.pro index 9e2d3519e6..68d3b48086 100644 --- a/tests/auto/corelib/kernel/qmetaobjectbuilder/qmetaobjectbuilder.pro +++ b/tests/auto/corelib/kernel/qmetaobjectbuilder/qmetaobjectbuilder.pro @@ -1,6 +1,6 @@ CONFIG += testcase parallel_test TARGET = tst_qmetaobjectbuilder -QT = core-private gui-private testlib +QT = core-private testlib SOURCES = tst_qmetaobjectbuilder.cpp mac:CONFIG -= app_bundle DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/corelib/kernel/qpointer/qpointer.pro b/tests/auto/corelib/kernel/qpointer/qpointer.pro index 8786d07292..4b573cb6a5 100644 --- a/tests/auto/corelib/kernel/qpointer/qpointer.pro +++ b/tests/auto/corelib/kernel/qpointer/qpointer.pro @@ -1,7 +1,7 @@ CONFIG += testcase CONFIG += parallel_test TARGET = tst_qpointer -QT += testlib +QT = core testlib qtHaveModule(widgets): QT += widgets SOURCES = tst_qpointer.cpp DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/corelib/kernel/qsignalmapper/qsignalmapper.pro b/tests/auto/corelib/kernel/qsignalmapper/qsignalmapper.pro index 59660d4b07..526db5eef3 100644 --- a/tests/auto/corelib/kernel/qsignalmapper/qsignalmapper.pro +++ b/tests/auto/corelib/kernel/qsignalmapper/qsignalmapper.pro @@ -1,6 +1,6 @@ CONFIG += testcase CONFIG += parallel_test TARGET = tst_qsignalmapper -QT += testlib +QT = core testlib SOURCES = tst_qsignalmapper.cpp DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.pro b/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.pro index 66fe844b21..2496cd2f1e 100644 --- a/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.pro +++ b/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.pro @@ -1,4 +1,5 @@ TEMPLATE = lib +QT = core CONFIG += plugin HEADERS = plugin1.h SOURCES = plugin1.cpp diff --git a/tests/auto/corelib/plugin/qfactoryloader/plugin2/plugin2.pro b/tests/auto/corelib/plugin/qfactoryloader/plugin2/plugin2.pro index aec057e80c..e70ed4fb25 100644 --- a/tests/auto/corelib/plugin/qfactoryloader/plugin2/plugin2.pro +++ b/tests/auto/corelib/plugin/qfactoryloader/plugin2/plugin2.pro @@ -1,4 +1,5 @@ TEMPLATE = lib +QT = core CONFIG += plugin HEADERS = plugin2.h SOURCES = plugin2.cpp diff --git a/tests/auto/corelib/plugin/quuid/testProcessUniqueness/testProcessUniqueness.pro b/tests/auto/corelib/plugin/quuid/testProcessUniqueness/testProcessUniqueness.pro index 9ce1ef3dcf..b2f7aaf2d3 100644 --- a/tests/auto/corelib/plugin/quuid/testProcessUniqueness/testProcessUniqueness.pro +++ b/tests/auto/corelib/plugin/quuid/testProcessUniqueness/testProcessUniqueness.pro @@ -1,4 +1,5 @@ SOURCES = main.cpp +QT = core CONFIG += console DESTDIR = ./ diff --git a/tests/auto/corelib/statemachine/qstatemachine/qstatemachine.pro b/tests/auto/corelib/statemachine/qstatemachine/qstatemachine.pro index b830efe3a5..f6fbbc83c6 100644 --- a/tests/auto/corelib/statemachine/qstatemachine/qstatemachine.pro +++ b/tests/auto/corelib/statemachine/qstatemachine/qstatemachine.pro @@ -1,7 +1,7 @@ CONFIG += testcase CONFIG += parallel_test TARGET = tst_qstatemachine -QT = core-private testlib gui +QT = core-private testlib qtHaveModule(widgets): QT += widgets SOURCES = tst_qstatemachine.cpp DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/corelib/tools/qbytedatabuffer/qbytedatabuffer.pro b/tests/auto/corelib/tools/qbytedatabuffer/qbytedatabuffer.pro index 135b1ff8c4..e23018f96a 100644 --- a/tests/auto/corelib/tools/qbytedatabuffer/qbytedatabuffer.pro +++ b/tests/auto/corelib/tools/qbytedatabuffer/qbytedatabuffer.pro @@ -1,4 +1,4 @@ TARGET = tst_qbytedatabuffer CONFIG += testcase -QT += core-private testlib +QT = core-private testlib SOURCES += tst_qbytedatabuffer.cpp diff --git a/tests/auto/corelib/tools/qtimezone/qtimezone.pro b/tests/auto/corelib/tools/qtimezone/qtimezone.pro index 2c53100857..fa2397a6bb 100644 --- a/tests/auto/corelib/tools/qtimezone/qtimezone.pro +++ b/tests/auto/corelib/tools/qtimezone/qtimezone.pro @@ -1,6 +1,6 @@ CONFIG += testcase parallel_test TARGET = tst_qtimezone -QT += core-private testlib +QT = core-private testlib SOURCES = tst_qtimezone.cpp DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 contains(QT_CONFIG,icu) { diff --git a/tests/auto/dbus/qdbusmarshall/qdbusmarshall.pro b/tests/auto/dbus/qdbusmarshall/qdbusmarshall.pro index 0578433d58..dfbb206324 100644 --- a/tests/auto/dbus/qdbusmarshall/qdbusmarshall.pro +++ b/tests/auto/dbus/qdbusmarshall/qdbusmarshall.pro @@ -4,6 +4,6 @@ TEMPLATE = subdirs CONFIG += ordered SUBDIRS = qpong test -QT += core-private testlib +QT = core-private testlib requires(contains(QT_CONFIG,private_tests)) diff --git a/tests/auto/other/modeltest/modeltest.cpp b/tests/auto/other/modeltest/modeltest.cpp index d356b26c54..a5233c4c3a 100644 --- a/tests/auto/other/modeltest/modeltest.cpp +++ b/tests/auto/other/modeltest/modeltest.cpp @@ -39,11 +39,9 @@ ** ****************************************************************************/ - -#include - #include "modeltest.h" +#include #include /*! -- cgit v1.2.3 From e7c58919275b35b2b970f38ed6d23fcf3b715380 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 8 Oct 2013 12:38:26 +0200 Subject: don't test Qt::codecForHtml() - build with -no-gui the function is a trivial wrapper for the QTextCodec one, so there is little point in explicitly testing it. Change-Id: I0c4950e5a54b7ffff9ba73a001cedb517497a596 Reviewed-by: Thiago Macieira --- tests/auto/corelib/codecs/qtextcodec/test/test.pro | 2 +- tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/auto/corelib/codecs/qtextcodec/test/test.pro b/tests/auto/corelib/codecs/qtextcodec/test/test.pro index ba16a75604..35b2b34690 100644 --- a/tests/auto/corelib/codecs/qtextcodec/test/test.pro +++ b/tests/auto/corelib/codecs/qtextcodec/test/test.pro @@ -1,6 +1,6 @@ CONFIG += testcase CONFIG += parallel_test -QT += testlib +QT = core testlib SOURCES = ../tst_qtextcodec.cpp TARGET = ../tst_qtextcodec diff --git a/tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp b/tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp index 6329160998..dd557b8d21 100644 --- a/tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp +++ b/tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp @@ -44,7 +44,6 @@ #include #include -#include #include #include #include @@ -288,7 +287,7 @@ void tst_QTextCodec::toUnicode_codecForHtml() QVERIFY(file.open(QFile::ReadOnly)); QByteArray data = file.readAll(); - QTextCodec *codec = Qt::codecForHtml(data); + QTextCodec *codec = QTextCodec::codecForHtml(data); codec->toUnicode(data); // this line crashes } -- cgit v1.2.3 From c0264050938c04723f7dc9295ef87cf41ab7a8ae Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 10 Oct 2013 18:05:36 +0200 Subject: normalize QMAKE_DEFAULT_{LIB,INC}DIRS the consumers of these variables use the strings for naive text-based "subtraction", which of course doesn't work particularly well when the paths contain "../", "./", and trailing slashes. Task-number: QTBUG-33714 Change-Id: I893c90e6f5c7cf18c9e6cb1e5be825a16509a2a4 Reviewed-by: Thiago Macieira Reviewed-by: Oswald Buddenhagen --- configure | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/configure b/configure index 5271e6ba1a..f7d770acef 100755 --- a/configure +++ b/configure @@ -3032,6 +3032,21 @@ unset tty eval `LC_ALL=C $TEST_COMPILER $SYSROOT_FLAG $TEST_COMPILER_CXXFLAGS -xc++ -E -v - < /dev/null 2>&1 > /dev/null | $AWK ' BEGIN { ORS = ""; FS = "="; incs = 0; libs = 0; } + +function normalize(dir) +{ + do { + odir = dir + gsub(/\\/[^/]+\\/\\.\\./, "", dir) + } while (dir != odir); + do { + odir = dir + gsub(/\\/\\./, "", dir) + } while (dir != odir); + sub("/$", "", dir); + return dir; +} + function quote(s) { # We only handle spaces @@ -3047,14 +3062,16 @@ function quote(s) /^\#include Date: Thu, 10 Oct 2013 18:17:35 +0200 Subject: de-duplicate QMAKE_DEFAULT_LIBDIRS after all but this time without reshuffling it. it's actually easy with awk. this makes the resulting qconfig.pri cleaner (and thus easier to debug). and configure needs a few millisecs less to finish. ^^ QMAKE_DEFAULT_INCDIRS doesn't appear to contain dupes to start with. Change-Id: I9eed2cf853cd15d0d24a885b1c3d69f22ffafb36 Reviewed-by: Thiago Macieira --- configure | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/configure b/configure index f7d770acef..afd850ab7b 100755 --- a/configure +++ b/configure @@ -3070,7 +3070,10 @@ $1 == "LIBRARY_PATH" { print "DEFAULT_LIBDIRS=\""; for (lib in library_paths) { dir = normalize(library_paths[lib]); - print quote(dir) " "; + if (!(dir in dirs)) { + print quote(dir) " "; + dirs[dir] = 1; + } } print "\"\n" } -- cgit v1.2.3 From 66e3e1f75b9698a8aaa92efeebff89f83afc83c4 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Fri, 14 Jun 2013 16:42:32 +0200 Subject: OS X: a dialog should always have an enabled titlebar close button MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit regardless of modality. Task-number: QTBUG-28385 Task-number: QTCREATORBUG-9264 Change-Id: Iaa608f6e742686d4068547766ec596e37c696a07 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoawindow.mm | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 7bdfd12314..bee6d635ec 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -450,7 +450,6 @@ NSUInteger QCocoaWindow::windowStyleMask(Qt::WindowFlags flags) { Qt::WindowType type = static_cast(int(flags & Qt::WindowType_Mask)); NSInteger styleMask = NSBorderlessWindowMask; - if ((type & Qt::Popup) == Qt::Popup) { if (!windowIsPopupType(type) && !(flags & Qt::FramelessWindowHint)) styleMask = (NSUtilityWindowMask | NSResizableWindowMask | NSClosableWindowMask | @@ -458,14 +457,21 @@ NSUInteger QCocoaWindow::windowStyleMask(Qt::WindowFlags flags) } else { // Filter flags for supported properties flags &= Qt::WindowType_Mask | Qt::FramelessWindowHint | Qt::WindowTitleHint | - Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint; + Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint | Qt::CustomizeWindowHint; if (flags == Qt::Window) { styleMask = (NSResizableWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSTitledWindowMask); } else if ((flags & Qt::Dialog) == Qt::Dialog) { - if (window()->modality() == Qt::NonModal) + if (flags & Qt::CustomizeWindowHint) { + styleMask = NSResizableWindowMask; + if (flags & Qt::WindowTitleHint) + styleMask |= NSTitledWindowMask; + if (flags & Qt::WindowCloseButtonHint) + styleMask |= NSClosableWindowMask; + if (flags & Qt::WindowMinimizeButtonHint) + styleMask |= NSMiniaturizableWindowMask; + } else { styleMask = NSResizableWindowMask | NSClosableWindowMask | NSTitledWindowMask; - else - styleMask = NSResizableWindowMask | NSTitledWindowMask; + } } else if (!(flags & Qt::FramelessWindowHint)) { if ((flags & Qt::Dialog) || (flags & Qt::WindowMaximizeButtonHint)) styleMask |= NSResizableWindowMask; -- cgit v1.2.3 From b271ddebfcda26839a02705f17e287a4686f36fb Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Tue, 15 Oct 2013 20:11:37 +0200 Subject: Ensure that context menus show even if the window is not active on Mac When using the mouse to show a context menu on Mac then even if the window is not active then it will show the menu for native applications. So this ensures that this is respected for context menus in Qt too. Task-number: QTBUG-31497 Change-Id: Ibfcb4b893b0e31d4ce36926a83c9214d130d8fa2 Reviewed-by: Gabriel de Dietrich Reviewed-by: Shawn Rutledge --- src/plugins/platforms/cocoa/qcocoawindow.h | 1 + src/plugins/platforms/cocoa/qcocoawindow.mm | 17 +++++++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h index 05bf657c1f..6598bf393e 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.h +++ b/src/plugins/platforms/cocoa/qcocoawindow.h @@ -204,6 +204,7 @@ public: // for QNSView static const int NoAlertRequest; NSInteger m_alertRequest; + id monitor; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index bee6d635ec..522b48a61e 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -213,6 +213,7 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw) , m_registerTouchCount(0) , m_resizableTransientParent(false) , m_alertRequest(NoAlertRequest) + , monitor(nil) { #ifdef QT_COCOA_ENABLE_WINDOW_DEBUG qDebug() << "QCocoaWindow::QCocoaWindow" << this; @@ -367,6 +368,11 @@ void QCocoaWindow::setVisible(bool visible) if ((window()->type() == Qt::Popup || window()->type() == Qt::Dialog || window()->type() == Qt::Tool) && [m_nsWindow isKindOfClass:[NSPanel class]]) { [(NSPanel *)m_nsWindow setWorksWhenModal:YES]; + if (!(parentCocoaWindow && window()->transientParent()->isActive()) && window()->type() == Qt::Popup) { + monitor = [NSEvent addGlobalMonitorForEventsMatchingMask:NSLeftMouseDownMask|NSRightMouseDownMask|NSOtherMouseDown handler:^(NSEvent *) { + QWindowSystemInterface::handleMouseEvent(window(), QPointF(-1, -1), QPointF(window()->framePosition() - QPointF(1, 1)), Qt::LeftButton); + }]; + } } } } @@ -403,6 +409,10 @@ void QCocoaWindow::setVisible(bool visible) } else { [m_contentView setHidden:YES]; } + if (monitor && window()->type() == Qt::Popup) { + [NSEvent removeMonitor:monitor]; + monitor = nil; + } if (parentCocoaWindow && window()->type() == Qt::Popup) { parentCocoaWindow->m_activePopupWindow = 0; if (m_resizableTransientParent @@ -849,10 +859,9 @@ NSWindow * QCocoaWindow::createNSWindow() // before the window is shown and needs a proper window.). if ((type & Qt::Popup) == Qt::Popup) [window setHasShadow:YES]; - else { - setWindowShadow(flags); - [window setHidesOnDeactivate: NO]; - } + else + setWindowShadow(flags); + [window setHidesOnDeactivate: NO]; #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7) { -- cgit v1.2.3 From 42c8c7e9dbf4c9e67b88bd16f0fe4e0d3c57857b Mon Sep 17 00:00:00 2001 From: James Turner Date: Tue, 15 Oct 2013 18:32:02 +0100 Subject: Support APPLE VAO extension on Mac. Since Mac lacks a compatibility profile, we often use the highest supported compatible version, 2.1; this lacks vertex-array-object (VAO) support in the API, but Apple provide a compatible extension. Extend the helper object to detect this case and make VAO support work. Change-Id: I75a74e048a0d188cec76bc5a4a9eafa4c9143740 Reviewed-by: Sean Harmer --- src/gui/opengl/qopenglvertexarrayobject.cpp | 40 +++++++++++++++++++---------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/src/gui/opengl/qopenglvertexarrayobject.cpp b/src/gui/opengl/qopenglvertexarrayobject.cpp index 16ed79ac10..1f039a8ca9 100644 --- a/src/gui/opengl/qopenglvertexarrayobject.cpp +++ b/src/gui/opengl/qopenglvertexarrayobject.cpp @@ -58,9 +58,15 @@ public: { Q_ASSERT(context); #if !defined(QT_OPENGL_ES_2) - GenVertexArrays = reinterpret_cast(context->getProcAddress("glGenVertexArrays")); - DeleteVertexArrays = reinterpret_cast(context->getProcAddress("glDeleteVertexArrays")); - BindVertexArray = reinterpret_cast(context->getProcAddress("glBindVertexArray")); + if (context->hasExtension(QByteArrayLiteral("GL_APPLE_vertex_array_object"))) { + GenVertexArrays = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glGenVertexArraysAPPLE"))); + DeleteVertexArrays = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glDeleteVertexArraysAPPLE"))); + BindVertexArray = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glBindVertexArrayAPPLE"))); + } else { + GenVertexArrays = reinterpret_cast(context->getProcAddress("glGenVertexArrays")); + DeleteVertexArrays = reinterpret_cast(context->getProcAddress("glDeleteVertexArrays")); + BindVertexArray = reinterpret_cast(context->getProcAddress("glBindVertexArray")); + } #else GenVertexArrays = reinterpret_cast(context->getProcAddress("glGenVertexArraysOES")); DeleteVertexArrays = reinterpret_cast(context->getProcAddress("glDeleteVertexArraysOES")); @@ -84,7 +90,7 @@ public: } private: - // Function signatures are equivalent between desktop core, ARB and ES 2 extensions + // Function signatures are equivalent between desktop core, ARB, APPLE and ES 2 extensions void (QOPENGLF_APIENTRYP GenVertexArrays)(GLsizei n, GLuint *arrays); void (QOPENGLF_APIENTRYP DeleteVertexArrays)(GLsizei n, const GLuint *arrays); void (QOPENGLF_APIENTRYP BindVertexArray)(GLuint array); @@ -109,8 +115,8 @@ public: #if defined(QT_OPENGL_ES_2) delete vaoFuncs; #else - if (vaoFuncsType == ARB) - delete vaoFuncs.arb; + if ((vaoFuncsType == ARB) || (vaoFuncsType == APPLE)) + delete vaoFuncs.helper; #endif } @@ -130,13 +136,14 @@ public: union { QOpenGLFunctions_3_0 *core_3_0; QOpenGLFunctions_3_2_Core *core_3_2; - QVertexArrayObjectHelper *arb; + QVertexArrayObjectHelper *helper; } vaoFuncs; enum { NotSupported, Core_3_0, Core_3_2, - ARB + ARB, + APPLE } vaoFuncsType; #endif QOpenGLContext *context; @@ -181,9 +188,13 @@ bool QOpenGLVertexArrayObjectPrivate::create() vaoFuncs.core_3_0->initializeOpenGLFunctions(); vaoFuncs.core_3_0->glGenVertexArrays(1, &vao); } else if (ctx->hasExtension("GL_ARB_vertex_array_object")) { - vaoFuncs.arb = new QVertexArrayObjectHelper(ctx); + vaoFuncs.helper = new QVertexArrayObjectHelper(ctx); vaoFuncsType = ARB; - vaoFuncs.arb->glGenVertexArrays(1, &vao); + vaoFuncs.helper->glGenVertexArrays(1, &vao); + } else if (ctx->hasExtension(QByteArrayLiteral("GL_APPLE_vertex_array_object"))) { + vaoFuncs.helper = new QVertexArrayObjectHelper(ctx); + vaoFuncsType = APPLE; + vaoFuncs.helper->glGenVertexArrays(1, &vao); } #endif return (vao != 0); @@ -205,7 +216,8 @@ void QOpenGLVertexArrayObjectPrivate::destroy() vaoFuncs.core_3_0->glDeleteVertexArrays(1, &vao); break; case ARB: - vaoFuncs.arb->glDeleteVertexArrays(1, &vao); + case APPLE: + vaoFuncs.helper->glDeleteVertexArrays(1, &vao); break; case NotSupported: break; @@ -236,7 +248,8 @@ void QOpenGLVertexArrayObjectPrivate::bind() vaoFuncs.core_3_0->glBindVertexArray(vao); break; case ARB: - vaoFuncs.arb->glBindVertexArray(vao); + case APPLE: + vaoFuncs.helper->glBindVertexArray(vao); break; case NotSupported: break; @@ -258,7 +271,8 @@ void QOpenGLVertexArrayObjectPrivate::release() vaoFuncs.core_3_0->glBindVertexArray(0); break; case ARB: - vaoFuncs.arb->glBindVertexArray(0); + case APPLE: + vaoFuncs.helper->glBindVertexArray(0); break; case NotSupported: break; -- cgit v1.2.3 From 15ddb91bc767b55297cbb35f293f5900379fee18 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Fri, 20 Sep 2013 11:45:54 +0200 Subject: Print non-default categories in default message handler Change the default output of the logging framework to prefix messages with a 'category: ' in case the category is not "default", so that e.g. QLoggingCategory cat("qt.core.codes.windows"); qCWarning(cat) << "MultiByteToWideChar: Cannot convert multibyte text"; will print qt.core.codes.windows: MultiByteToWideChar: Cannot convert multibyte text while output from qWarning etc will show unaltered output. This should help users to discover categories, and to group output together. Change-Id: Iac2e1514f7dc5671966c36a440a119c857564cfc Reviewed-by: Thiago Macieira Reviewed-by: hjk --- src/corelib/global/qlogging.cpp | 7 ++++++- tests/auto/corelib/global/qlogging/app/main.cpp | 4 ++++ tests/auto/corelib/global/qlogging/tst_qlogging.cpp | 17 ++++++++++------- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp index 7a759ef8f5..0a261acc77 100644 --- a/src/corelib/global/qlogging.cpp +++ b/src/corelib/global/qlogging.cpp @@ -549,6 +549,7 @@ static const char functionTokenC[] = "%{function}"; static const char pidTokenC[] = "%{pid}"; static const char appnameTokenC[] = "%{appname}"; static const char threadidTokenC[] = "%{threadid}"; +static const char ifCategoryTokenC[] = "%{if-category}"; static const char ifDebugTokenC[] = "%{if-debug}"; static const char ifWarningTokenC[] = "%{if-warning}"; static const char ifCriticalTokenC[] = "%{if-critical}"; @@ -556,7 +557,7 @@ static const char ifFatalTokenC[] = "%{if-fatal}"; static const char endifTokenC[] = "%{endif}"; static const char emptyTokenC[] = ""; -static const char defaultPattern[] = "%{message}"; +static const char defaultPattern[] = "%{if-category}%{category}: %{endif}%{message}"; struct QMessagePattern { @@ -675,6 +676,7 @@ void QMessagePattern::setPattern(const QString &pattern) tokens[i] = LEVEL; \ inIf = true; \ } + IF_TOKEN(ifCategoryTokenC) IF_TOKEN(ifDebugTokenC) IF_TOKEN(ifWarningTokenC) IF_TOKEN(ifCriticalTokenC) @@ -837,6 +839,9 @@ Q_CORE_EXPORT QString qMessageFormatString(QtMsgType type, const QMessageLogCont message.append(QLatin1String("0x")); message.append(QString::number(qlonglong(QThread::currentThread()->currentThread()), 16)); #endif + } else if (token == ifCategoryTokenC) { + if (!context.category || (strcmp(context.category, "default") == 0)) + skip = true; #define HANDLE_IF_TOKEN(LEVEL) \ } else if (token == if##LEVEL##TokenC) { \ skip = type != Qt##LEVEL##Msg; diff --git a/tests/auto/corelib/global/qlogging/app/main.cpp b/tests/auto/corelib/global/qlogging/app/main.cpp index 14416a914d..621059caad 100644 --- a/tests/auto/corelib/global/qlogging/app/main.cpp +++ b/tests/auto/corelib/global/qlogging/app/main.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ #include +#include struct T { T() { qDebug("static constructor"); } @@ -57,6 +58,9 @@ int main(int argc, char **argv) qWarning("qWarning"); qCritical("qCritical"); + QLoggingCategory cat("category"); + qCWarning(cat) << "qDebug with category"; + qSetMessagePattern(QString()); qDebug("qDebug2"); diff --git a/tests/auto/corelib/global/qlogging/tst_qlogging.cpp b/tests/auto/corelib/global/qlogging/tst_qlogging.cpp index 94387704f6..31a4254344 100644 --- a/tests/auto/corelib/global/qlogging/tst_qlogging.cpp +++ b/tests/auto/corelib/global/qlogging/tst_qlogging.cpp @@ -666,13 +666,14 @@ void tst_qmessagehandler::qMessagePattern() // qDebug() << output; QVERIFY(!output.isEmpty()); - QVERIFY(output.contains("debug 45 T::T static constructor")); + QVERIFY(output.contains("debug 46 T::T static constructor")); // we can't be sure whether the QT_MESSAGE_PATTERN is already destructed QVERIFY(output.contains("static destructor")); - QVERIFY(output.contains("debug tst_qlogging 56 main qDebug")); - QVERIFY(output.contains("warning tst_qlogging 57 main qWarning")); - QVERIFY(output.contains("critical tst_qlogging 58 main qCritical")); - QVERIFY(output.contains("debug tst_qlogging 62 main qDebug2")); + QVERIFY(output.contains("debug tst_qlogging 57 main qDebug")); + QVERIFY(output.contains("warning tst_qlogging 58 main qWarning")); + QVERIFY(output.contains("critical tst_qlogging 59 main qCritical")); + QVERIFY(output.contains("warning tst_qlogging 62 main qDebug with category ")); + QVERIFY(output.contains("debug tst_qlogging 66 main qDebug2")); environment = m_baseEnvironment; environment.prepend("QT_MESSAGE_PATTERN=\"PREFIX: %{unknown} %{message}\""); @@ -710,7 +711,8 @@ void tst_qmessagehandler::qMessagePattern() QByteArray expected = "static constructor\n" "[debug] qDebug\n" "[warning] qWarning\n" - "[critical] qCritical\n"; + "[critical] qCritical\n" + "[warning] qDebug with category \n"; #ifdef Q_OS_WIN output.replace("\r\n", "\n"); #endif @@ -727,7 +729,7 @@ void tst_qmessagehandler::qMessagePatternIf() const QString appExe = m_appDir + "/app"; QStringList environment = m_baseEnvironment; - environment.prepend("QT_MESSAGE_PATTERN=\"[%{if-debug}D%{endif}%{if-warning}W%{endif}%{if-critical}C%{endif}%{if-fatal}F%{endif}] %{message}\""); + environment.prepend("QT_MESSAGE_PATTERN=\"[%{if-debug}D%{endif}%{if-warning}W%{endif}%{if-critical}C%{endif}%{if-fatal}F%{endif}] %{if-category}%{category}: %{endif}%{message}\""); process.setEnvironment(environment); process.start(appExe); QVERIFY2(process.waitForStarted(), qPrintable( @@ -745,6 +747,7 @@ void tst_qmessagehandler::qMessagePatternIf() QVERIFY(output.contains("[D] qDebug")); QVERIFY(output.contains("[W] qWarning")); QVERIFY(output.contains("[C] qCritical")); + QVERIFY(output.contains("[W] category: qDebug with category")); QVERIFY(output.contains("[D] qDebug2")); // -- cgit v1.2.3 From 5c92a8b70a0349cc13a0758ef674cf817fc41381 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 14 Oct 2013 15:09:00 +0200 Subject: Xcode: Dynamically choose release/debug libs based on current configuration Non-framework builds would automatically link to whatever Qt library matched the config at the time of running qmake, eg hard-coded to libQtCore_debug, while Xcode itself allowed the user to switch between release and debug configurations. We now append an Xcode settings variable to the library path, which gets resolved at build time depending on the current config in Xcode. Change-Id: I12873e38a28d9595ef3fd0ae0ad849e6744833a9 Reviewed-by: Oswald Buddenhagen Reviewed-by: Andy Shaw --- mkspecs/features/mac/default_pre.prf | 6 ++++++ mkspecs/features/resolve_config.prf | 37 ++++++++++++++++++++++++++++------- qmake/generators/mac/pbuilder_pbx.cpp | 14 +++++++++++++ 3 files changed, 50 insertions(+), 7 deletions(-) diff --git a/mkspecs/features/mac/default_pre.prf b/mkspecs/features/mac/default_pre.prf index e535c4d9e9..c0596d5ef0 100644 --- a/mkspecs/features/mac/default_pre.prf +++ b/mkspecs/features/mac/default_pre.prf @@ -23,3 +23,9 @@ isEmpty(QMAKE_XCODE_VERSION) { isEmpty(QMAKE_XCODE_VERSION): error("Could not resolve Xcode version.") unset(xcode_version) } + +# These two variables are used by the xcode_dynamic_library_suffix +# feature, which allows Xcode to choose the Qt libraries to link to +# at build time, depending on the current Xcode SDK and configuration. +QMAKE_XCODE_LIBRARY_SUFFIX = $$qtPlatformTargetSuffix() +QMAKE_XCODE_LIBRARY_SUFFIX_SETTING = QT_LIBRARY_SUFFIX diff --git a/mkspecs/features/resolve_config.prf b/mkspecs/features/resolve_config.prf index 41e82b2382..3884598a94 100644 --- a/mkspecs/features/resolve_config.prf +++ b/mkspecs/features/resolve_config.prf @@ -36,11 +36,34 @@ CONFIG(debug, debug|release): \ else: \ CONFIG -= debug -debug_and_release { - !macx-xcode: addExclusiveBuilds(debug, Debug, release, Release) -} else: fix_output_dirs { - debug: \ - fixExclusiveOutputDirs(debug, release) - else: \ - fixExclusiveOutputDirs(release, debug) +!macx-xcode { + debug_and_release { + addExclusiveBuilds(debug, Debug, release, Release) + } else: fix_output_dirs { + debug: \ + fixExclusiveOutputDirs(debug, release) + else: \ + fixExclusiveOutputDirs(release, debug) + } +} else { + # The Xcode generator always generates project files with + # debug and release configurations, regardless of whether + # or not debug_and_release is active. + for(build, $$list(debug release)) { + suffix = + contains(QT_CONFIG, debug_and_release) { + equals(build, debug): \ + suffix = _debug + } else { + contains(QT_CONFIG, debug): \ + suffix = _debug + } + + library_suffix_$${build}.name = $$QMAKE_XCODE_LIBRARY_SUFFIX_SETTING + library_suffix_$${build}.value = $$suffix + library_suffix_$${build}.build = $$build + QMAKE_MAC_XCODE_SETTINGS += library_suffix_$${build} + + CONFIG *= xcode_dynamic_library_suffix + } } diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp index ac9e4cc71a..03887e7938 100644 --- a/qmake/generators/mac/pbuilder_pbx.cpp +++ b/qmake/generators/mac/pbuilder_pbx.cpp @@ -874,6 +874,20 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) debug_msg(1, "pbuilder: Found library (%s) via PRL %s (%s)", opt.toLatin1().constData(), lib_file.toLatin1().constData(), library.toLatin1().constData()); remove = true; + + if (project->isActiveConfig("xcode_dynamic_library_suffix")) { + QString suffixSetting = project->first("QMAKE_XCODE_LIBRARY_SUFFIX_SETTING").toQString(); + if (!suffixSetting.isEmpty()) { + QString librarySuffix = project->first("QMAKE_XCODE_LIBRARY_SUFFIX").toQString(); + suffixSetting = "$(" + suffixSetting + ")"; + if (!librarySuffix.isEmpty()) { + library = library.replace(librarySuffix, suffixSetting); + name = name.remove(librarySuffix); + } else { + library = library.replace(name, name + suffixSetting); + } + } + } } } } -- cgit v1.2.3 From 77adddae373cb9e5019a1d789014925330fb8d75 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 15 Oct 2013 12:40:35 -0700 Subject: Move the Apple Clang specific features outside of the C++11 section MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Those are not related to C++11, so move them to the Clang detection block. Change-Id: I80b298e1df5f74a865d743625895e0f01cb5fd6b Reviewed-by: Gabriel de Dietrich Reviewed-by: Morten Johan Sørvig --- src/corelib/global/qcompilerdetection.h | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h index 280c5066a6..d02e4cf199 100644 --- a/src/corelib/global/qcompilerdetection.h +++ b/src/corelib/global/qcompilerdetection.h @@ -161,6 +161,13 @@ # /* Compatibility with older Clang versions */ # define __has_extension __has_feature # endif +# if defined(__APPLE__) + /* Apple/clang specific features */ +# define Q_DECL_CF_RETURNS_RETAINED __attribute__((cf_returns_retained)) +# ifdef __OBJC__ +# define Q_DECL_NS_RETURNS_AUTORELEASED __attribute__((ns_returns_autoreleased)) +# endif +# endif # else /* Plain GCC */ # if (__GNUC__ * 100 + __GNUC_MINOR__) >= 405 @@ -620,14 +627,6 @@ # endif #endif // Q_CC_CLANG -#if defined(Q_CC_CLANG) && defined(__APPLE__) -/* Apple/clang specific features */ -# define Q_DECL_CF_RETURNS_RETAINED __attribute__((cf_returns_retained)) -# ifdef __OBJC__ -# define Q_DECL_NS_RETURNS_AUTORELEASED __attribute__((ns_returns_autoreleased)) -# endif -#endif - #if defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && !defined(Q_CC_CLANG) # if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L # if (__GNUC__ * 100 + __GNUC_MINOR__) >= 403 -- cgit v1.2.3 From 24b817f20a7956470971b64436f6b8f1f9745115 Mon Sep 17 00:00:00 2001 From: Marcel Krems Date: Wed, 9 Oct 2013 04:24:06 +0200 Subject: Fix compilation with Clang and libc++ under Linux src/plugins/platforms/xcb/qxcbsessionmanager.cpp:205:80: error: use of undeclared identifier 'ERANGE' while (getpwuid_r(geteuid(), &entry, buf.data(), buf.size(), &entryPtr) == ERANGE) { src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp:173:28: error: use of undeclared identifier 'LC_CTYPE' char *name = setlocale(LC_CTYPE, (char *)0); Change-Id: Ide6f3072e9158eef412973ce0a72babb41b695f0 Reviewed-by: Thiago Macieira --- src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp | 1 + src/plugins/platforms/xcb/qxcbsessionmanager.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp index c222b62a36..b5e3aa741e 100644 --- a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp +++ b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp @@ -55,6 +55,7 @@ #include #endif +#include // LC_CTYPE #include // strchr, strncmp, etc. #include // strncasecmp diff --git a/src/plugins/platforms/xcb/qxcbsessionmanager.cpp b/src/plugins/platforms/xcb/qxcbsessionmanager.cpp index 6abe24b7ab..9d81c8e224 100644 --- a/src/plugins/platforms/xcb/qxcbsessionmanager.cpp +++ b/src/plugins/platforms/xcb/qxcbsessionmanager.cpp @@ -48,6 +48,7 @@ #include #include #include +#include // ERANGE class QSmSocketReceiver : public QObject -- cgit v1.2.3 From 6a63554bf8226b4ffcf23e45627e6e7920671fac Mon Sep 17 00:00:00 2001 From: John Layt Date: Tue, 15 Oct 2013 17:36:36 +0200 Subject: QDateTime - Fix toTimeSpec() for invalid datetimes Check if the datetime is valid before converting it to a different time spec. If it is invalid then just change the spec to keep behavior consistent with 5.1. Task-number: QTBUG-34020 Change-Id: I6630ec1d50f810a2178ab3222bd32af018085f81 Reviewed-by: Thiago Macieira --- src/corelib/tools/qdatetime.cpp | 33 ++++++++++++++++++++-- .../auto/corelib/tools/qdatetime/tst_qdatetime.cpp | 21 ++++++++++++++ 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index 9ddb96b424..dec4d9aaa4 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -3921,7 +3921,16 @@ qint64 QDateTime::msecsTo(const QDateTime &other) const QDateTime QDateTime::toTimeSpec(Qt::TimeSpec spec) const { - return fromMSecsSinceEpoch(toMSecsSinceEpoch(), spec, 0); + if (d->m_spec == spec && (spec == Qt::UTC || spec == Qt::LocalTime)) + return *this; + + if (!isValid()) { + QDateTime ret = *this; + ret.setTimeSpec(spec); + return ret; + } + + return fromMSecsSinceEpoch(d->toMSecsSinceEpoch(), spec, 0); } /*! @@ -3939,7 +3948,16 @@ QDateTime QDateTime::toTimeSpec(Qt::TimeSpec spec) const QDateTime QDateTime::toOffsetFromUtc(int offsetSeconds) const { - return fromMSecsSinceEpoch(toMSecsSinceEpoch(), Qt::OffsetFromUTC, offsetSeconds); + if (d->m_spec == Qt::OffsetFromUTC && d->m_offsetFromUtc == offsetSeconds) + return *this; + + if (!isValid()) { + QDateTime ret = *this; + ret.setOffsetFromUtc(offsetSeconds); + return ret; + } + + return fromMSecsSinceEpoch(d->toMSecsSinceEpoch(), Qt::OffsetFromUTC, offsetSeconds); } #ifndef QT_BOOTSTRAPPED @@ -3953,7 +3971,16 @@ QDateTime QDateTime::toOffsetFromUtc(int offsetSeconds) const QDateTime QDateTime::toTimeZone(const QTimeZone &timeZone) const { - return fromMSecsSinceEpoch(toMSecsSinceEpoch(), timeZone); + if (d->m_spec == Qt::TimeZone && d->m_timeZone == timeZone) + return *this; + + if (!isValid()) { + QDateTime ret = *this; + ret.setTimeZone(timeZone); + return ret; + } + + return fromMSecsSinceEpoch(d->toMSecsSinceEpoch(), timeZone); } #endif // QT_BOOTSTRAPPED diff --git a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp index b8b970121c..0c560df423 100644 --- a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp +++ b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp @@ -147,6 +147,8 @@ private slots: void daylightTransitions() const; void timeZones() const; + void invalid() const; + private: bool europeanTimeZone; QDate defDate() const { return QDate(1900, 1, 1); } @@ -2899,5 +2901,24 @@ void tst_QDateTime::timeZones() const QCOMPARE(hourAfterStd.toMSecsSinceEpoch(), dstToStdMSecs + 3600000); } +void tst_QDateTime::invalid() const +{ + QDateTime invalidDate = QDateTime(QDate(0, 0, 0), QTime(-1, -1, -1)); + QCOMPARE(invalidDate.isValid(), false); + QCOMPARE(invalidDate.timeSpec(), Qt::LocalTime); + + QDateTime utcDate = invalidDate.toUTC(); + QCOMPARE(utcDate.isValid(), false); + QCOMPARE(utcDate.timeSpec(), Qt::UTC); + + QDateTime offsetDate = invalidDate.toOffsetFromUtc(3600); + QCOMPARE(offsetDate.isValid(), false); + QCOMPARE(offsetDate.timeSpec(), Qt::OffsetFromUTC); + + QDateTime tzDate = invalidDate.toTimeZone(QTimeZone("Europe/Oslo")); + QCOMPARE(tzDate.isValid(), false); + QCOMPARE(tzDate.timeSpec(), Qt::TimeZone); +} + QTEST_APPLESS_MAIN(tst_QDateTime) #include "tst_qdatetime.moc" -- cgit v1.2.3 From d0b419e35521d50f1409de84f99ded3b9a7ab01d Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Mon, 7 Oct 2013 00:11:49 +0200 Subject: QGraphicsItemAnimation: save some string data (text size -= 1K) Also changed the 'step' range check to treat NaNs as invalid, too. Change-Id: I993c5efffcf7140fba8f80a7db499cd2335867e0 Reviewed-by: Stephen Kelly --- .../graphicsview/qgraphicsitemanimation.cpp | 63 +++++++++------------- 1 file changed, 26 insertions(+), 37 deletions(-) diff --git a/src/widgets/graphicsview/qgraphicsitemanimation.cpp b/src/widgets/graphicsview/qgraphicsitemanimation.cpp index 5dc3e1159e..ff98c147fe 100644 --- a/src/widgets/graphicsview/qgraphicsitemanimation.cpp +++ b/src/widgets/graphicsview/qgraphicsitemanimation.cpp @@ -97,6 +97,15 @@ QT_BEGIN_NAMESPACE +static inline bool check_step_valid(qreal step, const char *method) +{ + if (!(step >= 0 && step <= 1)) { + qWarning("QGraphicsItemAnimation::%s: invalid step = %f", method, step); + return false; + } + return true; +} + class QGraphicsItemAnimationPrivate { public: @@ -169,10 +178,8 @@ qreal QGraphicsItemAnimationPrivate::linearValueForStep(qreal step, QList void QGraphicsItemAnimationPrivate::insertUniquePair(qreal step, qreal value, QList *binList, const char* method) { - if (step < 0.0 || step > 1.0) { - qWarning("QGraphicsItemAnimation::%s: invalid step = %f", method, step); + if (!check_step_valid(step, method)) return; - } Pair pair(step, value); @@ -259,9 +266,7 @@ void QGraphicsItemAnimation::setTimeLine(QTimeLine *timeLine) */ QPointF QGraphicsItemAnimation::posAt(qreal step) const { - if (step < 0.0 || step > 1.0) - qWarning("QGraphicsItemAnimation::posAt: invalid step = %f", step); - + check_step_valid(step, "posAt"); return QPointF(d->linearValueForStep(step, &d->xPosition, d->startPos.x()), d->linearValueForStep(step, &d->yPosition, d->startPos.y())); } @@ -298,8 +303,7 @@ QList > QGraphicsItemAnimation::posList() const */ QMatrix QGraphicsItemAnimation::matrixAt(qreal step) const { - if (step < 0.0 || step > 1.0) - qWarning("QGraphicsItemAnimation::matrixAt: invalid step = %f", step); + check_step_valid(step, "matrixAt"); QMatrix matrix; if (!d->rotation.isEmpty()) @@ -320,9 +324,7 @@ QMatrix QGraphicsItemAnimation::matrixAt(qreal step) const */ qreal QGraphicsItemAnimation::rotationAt(qreal step) const { - if (step < 0.0 || step > 1.0) - qWarning("QGraphicsItemAnimation::rotationAt: invalid step = %f", step); - + check_step_valid(step, "rotationAt"); return d->linearValueForStep(step, &d->rotation); } @@ -357,9 +359,7 @@ QList > QGraphicsItemAnimation::rotationList() const */ qreal QGraphicsItemAnimation::xTranslationAt(qreal step) const { - if (step < 0.0 || step > 1.0) - qWarning("QGraphicsItemAnimation::xTranslationAt: invalid step = %f", step); - + check_step_valid(step, "xTranslationAt"); return d->linearValueForStep(step, &d->xTranslation); } @@ -370,9 +370,7 @@ qreal QGraphicsItemAnimation::xTranslationAt(qreal step) const */ qreal QGraphicsItemAnimation::yTranslationAt(qreal step) const { - if (step < 0.0 || step > 1.0) - qWarning("QGraphicsItemAnimation::yTranslationAt: invalid step = %f", step); - + check_step_valid(step, "yTranslationAt"); return d->linearValueForStep(step, &d->yTranslation); } @@ -409,8 +407,7 @@ QList > QGraphicsItemAnimation::translationList() const */ qreal QGraphicsItemAnimation::verticalScaleAt(qreal step) const { - if (step < 0.0 || step > 1.0) - qWarning("QGraphicsItemAnimation::verticalScaleAt: invalid step = %f", step); + check_step_valid(step, "verticalScaleAt"); return d->linearValueForStep(step, &d->verticalScale, 1); } @@ -422,9 +419,7 @@ qreal QGraphicsItemAnimation::verticalScaleAt(qreal step) const */ qreal QGraphicsItemAnimation::horizontalScaleAt(qreal step) const { - if (step < 0.0 || step > 1.0) - qWarning("QGraphicsItemAnimation::horizontalScaleAt: invalid step = %f", step); - + check_step_valid(step, "horizontalScaleAt"); return d->linearValueForStep(step, &d->horizontalScale, 1); } @@ -461,9 +456,7 @@ QList > QGraphicsItemAnimation::scaleList() const */ qreal QGraphicsItemAnimation::verticalShearAt(qreal step) const { - if (step < 0.0 || step > 1.0) - qWarning("QGraphicsItemAnimation::verticalShearAt: invalid step = %f", step); - + check_step_valid(step, "verticalShearAt"); return d->linearValueForStep(step, &d->verticalShear, 0); } @@ -474,9 +467,7 @@ qreal QGraphicsItemAnimation::verticalShearAt(qreal step) const */ qreal QGraphicsItemAnimation::horizontalShearAt(qreal step) const { - if (step < 0.0 || step > 1.0) - qWarning("QGraphicsItemAnimation::horizontalShearAt: invalid step = %f", step); - + check_step_valid(step, "horizontalShearAt"); return d->linearValueForStep(step, &d->horizontalShear, 0); } @@ -529,19 +520,17 @@ void QGraphicsItemAnimation::clear() Sets the current \a step value for the animation, causing the transformations scheduled at this step to be performed. */ -void QGraphicsItemAnimation::setStep(qreal x) +void QGraphicsItemAnimation::setStep(qreal step) { - if (x < 0.0 || x > 1.0) { - qWarning("QGraphicsItemAnimation::setStep: invalid step = %f", x); + if (!check_step_valid(step, "setStep")) return; - } - beforeAnimationStep(x); + beforeAnimationStep(step); - d->step = x; + d->step = step; if (d->item) { if (!d->xPosition.isEmpty() || !d->yPosition.isEmpty()) - d->item->setPos(posAt(x)); + d->item->setPos(posAt(step)); if (!d->rotation.isEmpty() || !d->verticalScale.isEmpty() || !d->horizontalScale.isEmpty() @@ -549,11 +538,11 @@ void QGraphicsItemAnimation::setStep(qreal x) || !d->horizontalShear.isEmpty() || !d->xTranslation.isEmpty() || !d->yTranslation.isEmpty()) { - d->item->setMatrix(d->startMatrix * matrixAt(x)); + d->item->setMatrix(d->startMatrix * matrixAt(step)); } } - afterAnimationStep(x); + afterAnimationStep(step); } /*! -- cgit v1.2.3 From 021c79f038c218a55b145fafcda5c59cf3a309d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Str=C3=B8mme?= Date: Fri, 11 Oct 2013 14:55:33 +0200 Subject: Android: Use java.util.Random in qrand() Android does not provide rand_r(), so we would fall back to rand() and srand() which means we where not keeping the promise of qrand and qsrand being thread-safe. As a replacement we can use the Java api and have one Random object for each thread. Task-number: QTBUG-32814 Change-Id: Id46d195a0bb122bc7a5a8de43bdf088e11a9c42e Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/corelib/global/qglobal.cpp | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index ff2c4bbe5e..1dd77c5859 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -76,6 +76,10 @@ #include #endif +#if defined(Q_OS_ANDROID) +#include +#endif + QT_BEGIN_NAMESPACE #if !QT_DEPRECATED_SINCE(5, 0) @@ -2335,6 +2339,9 @@ typedef uint SeedStorageType; typedef QThreadStorage SeedStorage; Q_GLOBAL_STATIC(SeedStorage, randTLS) // Thread Local Storage for seed value +#elif defined(Q_OS_ANDROID) +typedef QThreadStorage AndroidRandomStorage; +Q_GLOBAL_STATIC(AndroidRandomStorage, randomTLS) #endif /*! @@ -2368,6 +2375,16 @@ void qsrand(uint seed) //global static object, fallback to srand(seed) srand(seed); } +#elif defined(Q_OS_ANDROID) + QJNIObjectPrivate random = QJNIObjectPrivate("java/util/Random", + "(J)V", + jlong(seed)); + if (!random.isValid()) { + srand(seed); + return; + } + + randomTLS->setLocalData(random); #else // On Windows srand() and rand() already use Thread-Local-Storage // to store the seed between calls @@ -2409,6 +2426,25 @@ int qrand() //global static object, fallback to rand() return rand(); } +#elif defined(Q_OS_ANDROID) + AndroidRandomStorage *randomStorage = randomTLS(); + if (!randomStorage) + return rand(); + + QJNIObjectPrivate random; + if (!randomStorage->hasLocalData()) { + random = QJNIObjectPrivate("java/util/Random", + "(J)V", + jlong(1)); + if (!random.isValid()) + return rand(); + + randomStorage->setLocalData(random); + } else { + random = randomStorage->localData(); + } + + return random.callMethod("nextInt", "(I)I", RAND_MAX); #else // On Windows srand() and rand() already use Thread-Local-Storage // to store the seed between calls -- cgit v1.2.3 From f47958fa148d6ea9ece0bec3ca9ba67d9c68ea19 Mon Sep 17 00:00:00 2001 From: John Layt Date: Fri, 27 Sep 2013 16:32:44 +0100 Subject: QLocale - Mac fix typos in comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix some typos in the comments. Change-Id: I14eed0ffed74f0a60b05441430158f71cb530c01 Reviewed-by: Morten Johan Sørvig --- src/corelib/tools/qlocale_mac.mm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/tools/qlocale_mac.mm b/src/corelib/tools/qlocale_mac.mm index deb5d5eb1d..92dfba162c 100644 --- a/src/corelib/tools/qlocale_mac.mm +++ b/src/corelib/tools/qlocale_mac.mm @@ -193,7 +193,7 @@ static QString macToQtFormat(const QString &sys_fmt) // Qt does not support the following options case 'G': // Era (1..5): 4 = long, 1..3 = short, 5 = narrow case 'Y': // Year of Week (1..n): 1..n = padded number - case 'U': // Cyclic Yar Name (1..5): 4 = long, 1..3 = short, 5 = narrow + case 'U': // Cyclic Year Name (1..5): 4 = long, 1..3 = short, 5 = narrow case 'Q': // Quarter (1..4): 4 = long, 3 = short, 1..2 = padded number case 'q': // Standalone Quarter (1..4): 4 = long, 3 = short, 1..2 = padded number case 'w': // Week of Year (1..2): 1..2 = padded number @@ -257,7 +257,7 @@ static QString macToQtFormat(const QString &sys_fmt) case 's': // Seconds (1..2): 1..2 = padded number result += QString(repeat, c); break; - case 'S': // Fractional second (1..n): 1..n = tuncates to decimal places + case 'S': // Fractional second (1..n): 1..n = truncates to decimal places // Qt uses msecs either unpadded or padded to 3 places if (repeat < 3) result += QLatin1Char('z'); -- cgit v1.2.3 From 89ef515177fd5a0b5d95dcffd5fd0b0669e3625a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Thu, 5 Sep 2013 07:55:49 +0200 Subject: Add JSON parsing support to qmake. Add qjson* implementation files from corelib/json to the qmake build. Add a read-only compile mode, enabled by defining QT_JSON_READONLY. Add qmake built-in function parseJson(file, into) which parses a json file into the given variable. qmake uses a flat key -> value-list implementation for storing variables, which means that some hackery is need to represent arbitrarily nested JSON. Use a special "_KEYS_" variable for arrays and objects: Arrays: ["item1", "item2"] $${array._KEYS_} -> 0 1 2 $${array.0} -> "item1" $${array.1} -> "item2" Objects: { "key1" : "value1", "key2" : "value2" } $${object._KEYS_} -> key1 key2 $${object.key1} -> value1 $${object.key2} -> value2 Change-Id: I0aa2e4e4ae14fa25be8242bc16d3cffce32504d2 Reviewed-by: Lars Knoll --- qmake/Makefile.unix | 27 +++++++- qmake/Makefile.win32 | 13 +++- qmake/library/qmakebuiltins.cpp | 91 +++++++++++++++++++++++++- qmake/qmake.pri | 17 ++++- qmake/qmake.pro | 1 + src/corelib/json/qjsonarray.cpp | 2 +- src/corelib/json/qjsonarray.h | 2 +- src/corelib/json/qjsondocument.cpp | 6 +- src/corelib/json/qjsondocument.h | 4 +- src/corelib/json/qjsonobject.cpp | 2 +- src/corelib/json/qjsonobject.h | 2 +- src/corelib/json/qjsonvalue.cpp | 2 +- src/corelib/json/qjsonvalue.h | 2 +- tests/auto/tools/qmake/testdata/json/json.pro | 26 ++++++++ tests/auto/tools/qmake/testdata/json/test.json | 9 +++ tests/auto/tools/qmake/tst_qmake.cpp | 29 ++++++++ 16 files changed, 220 insertions(+), 15 deletions(-) create mode 100644 tests/auto/tools/qmake/testdata/json/json.pro create mode 100644 tests/auto/tools/qmake/testdata/json/test.json diff --git a/qmake/Makefile.unix b/qmake/Makefile.unix index a77b1b22dc..2f04a88a42 100644 --- a/qmake/Makefile.unix +++ b/qmake/Makefile.unix @@ -19,6 +19,7 @@ QOBJS=qtextcodec.o qutfcodec.o qstring.o qstringbuilder.o qtextstream.o qiodevic qabstractfileengine.o qtemporaryfile.o qmap.o qmetatype.o qsettings.o qsystemerror.o qlibraryinfo.o \ qvariant.o qvsnprintf.o qlocale.o qlocale_tools.o qlinkedlist.o qnumeric.o \ qcryptographichash.o qxmlstream.o qxmlutils.o qlogging.o \ + qjson.o qjsondocument.o qjsonparser.o qjsonarray.o qjsonobject.o qjsonvalue.o \ $(QTOBJS) @@ -80,6 +81,12 @@ DEPEND_SRC = \ $(SOURCE_PATH)/src/corelib/global/qlogging.cpp \ $(SOURCE_PATH)/src/corelib/plugin/qsystemlibrary.cpp \ $(SOURCE_PATH)/tools/shared/windows/registry.cpp \ + $(SOURCE_PATH)/src/corelib/json/qjson.cpp \ + $(SOURCE_PATH)/src/corelib/json/qjsondocument.cpp \ + $(SOURCE_PATH)/src/corelib/json/qjsonparser.cpp \ + $(SOURCE_PATH)/src/corelib/json/qjsonarray.cpp \ + $(SOURCE_PATH)/src/corelib/json/qjsonobject.cpp \ + $(SOURCE_PATH)/src/corelib/json/qjsonvalue.cpp \ $(QTSRCS) CPPFLAGS = -g $(EXTRA_CPPFLAGS) \ @@ -93,7 +100,7 @@ CPPFLAGS = -g $(EXTRA_CPPFLAGS) \ -DQT_BUILD_QMAKE -DQT_BOOTSTRAPPED -DPROEVALUATOR_FULL \ -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_NO_COMPONENT -DQT_NO_COMPRESS \ -DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -DQT_NO_DATASTREAM \ - -DQT_CRYPTOGRAPHICHASH_ONLY_SHA1 + -DQT_CRYPTOGRAPHICHASH_ONLY_SHA1 -DQT_JSON_READONLY CXXFLAGS = $(EXTRA_CXXFLAGS) $(CPPFLAGS) @@ -385,4 +392,22 @@ qsystemlibrary.o: $(SOURCE_PATH)/src/corelib/plugin/qsystemlibrary.cpp registry.o: $(SOURCE_PATH)/tools/shared/windows/registry.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/windows/registry.cpp +qjson.o: $(SOURCE_PATH)/src/corelib/json/qjson.cpp + $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/json/qjson.cpp + +qjsondocument.o: $(SOURCE_PATH)/src/corelib/json/qjsondocument.cpp + $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/json/qjsondocument.cpp + +qjsonparser.o: $(SOURCE_PATH)/src/corelib/json/qjsonparser.cpp + $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/json/qjsonparser.cpp + +qjsonarray.o: $(SOURCE_PATH)/src/corelib/json/qjsonarray.cpp + $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/json/qjsonarray.cpp + +qjsonobject.o: $(SOURCE_PATH)/src/corelib/json/qjsonobject.cpp + $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/json/qjsonobject.cpp + +qjsonvalue.o: $(SOURCE_PATH)/src/corelib/json/qjsonvalue.cpp + $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/json/qjsonvalue.cpp + # DO NOT DELETE THIS LINE -- make depend depends on it diff --git a/qmake/Makefile.win32 b/qmake/Makefile.win32 index 9a772d9760..c0d20111e9 100644 --- a/qmake/Makefile.win32 +++ b/qmake/Makefile.win32 @@ -41,7 +41,7 @@ CFLAGS_BARE = -c -Fo./ \ -DQT_BUILD_QMAKE -DQT_BOOTSTRAPPED -DPROEVALUATOR_FULL \ -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_NO_COMPONENT -DQT_NO_COMPRESS \ -DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -DQT_NO_DATASTREAM \ - -DUNICODE -DQT_CRYPTOGRAPHICHASH_ONLY_SHA1 + -DUNICODE -DQT_CRYPTOGRAPHICHASH_ONLY_SHA1 -DQT_JSON_READONLY CFLAGS = -Yuqmake_pch.h -FIqmake_pch.h -Fpqmake_pch.pch $(CFLAGS_BARE) $(CFLAGS) $(EXTRA_CPPFLAGS) CXXFLAGS_BARE = $(CFLAGS_BARE) @@ -120,7 +120,13 @@ QTOBJS= \ qxmlstream.obj \ qxmlutils.obj \ qnumeric.obj \ - qlogging.obj + qlogging.obj \ + qjson.obj \ + qjsondocument.obj \ + qjsonparser.obj \ + qjsonarray.obj \ + qjsonobject.obj \ + qjsonvalue.obj first all: qmake.exe @@ -207,5 +213,8 @@ qmake_pch.obj: {$(SOURCE_PATH)\src\corelib\xml}.cpp{}.obj:: $(CXX) $(CXXFLAGS) $< +{$(SOURCE_PATH)\src\corelib\json}.cpp{}.obj:: + $(CXX) $(CXXFLAGS) $< + {$(SOURCE_PATH)\tools\shared\windows}.cpp{}.obj:: $(CXX) $(CXXFLAGS) $< diff --git a/qmake/library/qmakebuiltins.cpp b/qmake/library/qmakebuiltins.cpp index 10ef523e15..9cefbc8572 100644 --- a/qmake/library/qmakebuiltins.cpp +++ b/qmake/library/qmakebuiltins.cpp @@ -56,6 +56,11 @@ #include #include #include +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) +# include +# include +# include +#endif #ifdef PROEVALUATOR_THREAD_SAFE # include #endif @@ -101,7 +106,7 @@ enum TestFunc { T_INVALID = 0, T_REQUIRES, T_GREATERTHAN, T_LESSTHAN, T_EQUALS, T_EXISTS, T_EXPORT, T_CLEAR, T_UNSET, T_EVAL, T_CONFIG, T_SYSTEM, T_DEFINED, T_CONTAINS, T_INFILE, - T_COUNT, T_ISEMPTY, T_INCLUDE, T_LOAD, T_DEBUG, T_LOG, T_MESSAGE, T_WARNING, T_ERROR, T_IF, + T_COUNT, T_ISEMPTY, T_PARSE_JSON, T_INCLUDE, T_LOAD, T_DEBUG, T_LOG, T_MESSAGE, T_WARNING, T_ERROR, T_IF, T_MKPATH, T_WRITE_FILE, T_TOUCH, T_CACHE }; @@ -178,6 +183,9 @@ void QMakeEvaluator::initFunctionStatics() { "infile", T_INFILE }, { "count", T_COUNT }, { "isEmpty", T_ISEMPTY }, +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + { "parseJson", T_PARSE_JSON }, +#endif { "load", T_LOAD }, { "include", T_INCLUDE }, { "debug", T_DEBUG }, @@ -286,6 +294,75 @@ quoteValue(const ProString &val) return ret; } +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) +static void addJsonValue(const QJsonValue &value, const QString &keyPrefix, ProValueMap *map); + +static void insertJsonKeyValue(const QString &key, const QStringList &values, ProValueMap *map) +{ + map->insert(ProKey(key), ProStringList(values)); +} + +static void addJsonArray(const QJsonArray &array, const QString &keyPrefix, ProValueMap *map) +{ + QStringList keys; + for (int i = 0; i < array.count(); ++i) { + keys.append(QString::number(i)); + addJsonValue(array.at(i), keyPrefix + QString::number(i), map); + } + insertJsonKeyValue(keyPrefix + QLatin1String("_KEYS_"), keys, map); +} + +static void addJsonObject(const QJsonObject &object, const QString &keyPrefix, ProValueMap *map) +{ + foreach (const QString &key, object.keys()) + addJsonValue(object.value(key), keyPrefix + key, map); + + insertJsonKeyValue(keyPrefix + QLatin1String("_KEYS_"), object.keys(), map); +} + +static void addJsonValue(const QJsonValue &value, const QString &keyPrefix, ProValueMap *map) +{ + switch (value.type()) { + case QJsonValue::Bool: + insertJsonKeyValue(keyPrefix, QStringList() << (value.toBool() ? QLatin1String("true") : QLatin1String("false")), map); + break; + case QJsonValue::Double: + insertJsonKeyValue(keyPrefix, QStringList() << QString::number(value.toDouble()), map); + break; + case QJsonValue::String: + insertJsonKeyValue(keyPrefix, QStringList() << value.toString(), map); + break; + case QJsonValue::Array: + addJsonArray(value.toArray(), keyPrefix + QLatin1Char('.'), map); + break; + case QJsonValue::Object: + addJsonObject(value.toObject(), keyPrefix + QLatin1Char('.'), map); + break; + default: + break; + } +} + +static QMakeEvaluator::VisitReturn parseJsonInto(const QByteArray &json, const QString &into, ProValueMap *value) +{ + QJsonDocument document = QJsonDocument::fromJson(json); + if (document.isNull()) + return QMakeEvaluator::ReturnFalse; + + QString currentKey = into + QLatin1Char('.'); + + // top-level item is either an array or object + if (document.isArray()) + addJsonArray(document.array(), currentKey, value); + else if (document.isObject()) + addJsonObject(document.object(), currentKey, value); + else + return QMakeEvaluator::ReturnFalse; + + return QMakeEvaluator::ReturnTrue; +} +#endif + QMakeEvaluator::VisitReturn QMakeEvaluator::writeFile(const QString &ctx, const QString &fn, QIODevice::OpenMode mode, const QString &contents) @@ -1278,6 +1355,18 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( m_valuemapStack.top()[var] = statics.fakeValue; return ReturnTrue; } +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + case T_PARSE_JSON: { + if (args.count() != 2) { + evalError(fL1S("parseJson(variable, into) requires two arguments.")); + return ReturnFalse; + } + + QByteArray json = values(args.at(0).toKey()).join(QLatin1Char(' ')).toUtf8(); + QString parseInto = args.at(1).toQString(m_tmp2); + return parseJsonInto(json, parseInto, &m_valuemapStack.top()); + } +#endif case T_INCLUDE: { if (args.count() < 1 || args.count() > 3) { evalError(fL1S("include(file, [into, [silent]]) requires one, two or three arguments.")); diff --git a/qmake/qmake.pri b/qmake/qmake.pri index 39959efe7b..5012bd0206 100644 --- a/qmake/qmake.pri +++ b/qmake/qmake.pri @@ -83,7 +83,13 @@ bootstrap { #Qt code qvsnprintf.cpp \ qxmlstream.cpp \ qxmlutils.cpp \ - qlogging.cpp + qlogging.cpp \ + qjson.cpp \ + qjsondocument.cpp \ + qjsonparser.cpp \ + qjsonarray.cpp \ + qjsonobject.cpp \ + qjsonvalue.cpp HEADERS+= \ qbitarray.h \ @@ -126,7 +132,14 @@ bootstrap { #Qt code quuid.h \ qvector.h \ qxmlstream.h \ - qxmlutils.h + qxmlutils.h \ + qjson.h \ + qjsondocument.h \ + qjsonparser.h \ + qjsonwriter.h \ + qjsonarray.h \ + qjsonobject.h \ + qjsonvalue.h unix { SOURCES += qfilesystemengine_unix.cpp qfilesystemiterator_unix.cpp qfsfileengine_unix.cpp diff --git a/qmake/qmake.pro b/qmake/qmake.pro index 568ad41ce1..e680942716 100644 --- a/qmake/qmake.pro +++ b/qmake/qmake.pro @@ -20,6 +20,7 @@ VPATH += $$QT_SOURCE_TREE/src/corelib/global \ $$QT_SOURCE_TREE/src/corelib/plugin \ $$QT_SOURCE_TREE/src/corelib/xml \ $$QT_SOURCE_TREE/src/corelib/io \ + $$QT_SOURCE_TREE/src/corelib/json \ $$QT_SOURCE_TREE/tools/shared/windows INCLUDEPATH += . \ diff --git a/src/corelib/json/qjsonarray.cpp b/src/corelib/json/qjsonarray.cpp index 8dd7f6092f..d81de89628 100644 --- a/src/corelib/json/qjsonarray.cpp +++ b/src/corelib/json/qjsonarray.cpp @@ -1089,7 +1089,7 @@ void QJsonArray::compact() } -#ifndef QT_NO_DEBUG_STREAM +#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY) QDebug operator<<(QDebug dbg, const QJsonArray &a) { if (!a.a) { diff --git a/src/corelib/json/qjsonarray.h b/src/corelib/json/qjsonarray.h index 1474ccae41..562e6accd7 100644 --- a/src/corelib/json/qjsonarray.h +++ b/src/corelib/json/qjsonarray.h @@ -211,7 +211,7 @@ private: QJsonPrivate::Array *a; }; -#ifndef QT_NO_DEBUG_STREAM +#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY) Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonArray &); #endif diff --git a/src/corelib/json/qjsondocument.cpp b/src/corelib/json/qjsondocument.cpp index 4806ac68d6..6e257df39d 100644 --- a/src/corelib/json/qjsondocument.cpp +++ b/src/corelib/json/qjsondocument.cpp @@ -303,10 +303,12 @@ QVariant QJsonDocument::toVariant() const \sa fromJson() */ +#ifndef QT_JSON_READONLY QByteArray QJsonDocument::toJson() const { return toJson(Indented); } +#endif /*! \enum QJsonDocument::JsonFormat @@ -338,6 +340,7 @@ QByteArray QJsonDocument::toJson() const \sa fromJson(), JsonFormat */ +#ifndef QT_JSON_READONLY QByteArray QJsonDocument::toJson(JsonFormat format) const { if (!d) @@ -352,6 +355,7 @@ QByteArray QJsonDocument::toJson(JsonFormat format) const return json; } +#endif /*! Parses a UTF-8 encoded JSON document and creates a QJsonDocument @@ -562,7 +566,7 @@ bool QJsonDocument::isNull() const return (d == 0); } -#ifndef QT_NO_DEBUG_STREAM +#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY) QDebug operator<<(QDebug dbg, const QJsonDocument &o) { if (!o.d) { diff --git a/src/corelib/json/qjsondocument.h b/src/corelib/json/qjsondocument.h index 0354262e2c..ea42d76b20 100644 --- a/src/corelib/json/qjsondocument.h +++ b/src/corelib/json/qjsondocument.h @@ -117,7 +117,7 @@ public: #ifdef Q_QDOC QByteArray toJson(JsonFormat format = Indented) const; -#else +#elif !defined(QT_JSON_READONLY) QByteArray toJson() const; //### Merge in Qt6 QByteArray toJson(JsonFormat format) const; #endif @@ -148,7 +148,7 @@ private: QJsonPrivate::Data *d; }; -#ifndef QT_NO_DEBUG_STREAM +#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY) Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonDocument &); #endif diff --git a/src/corelib/json/qjsonobject.cpp b/src/corelib/json/qjsonobject.cpp index 362d01384e..afc0d5f71f 100644 --- a/src/corelib/json/qjsonobject.cpp +++ b/src/corelib/json/qjsonobject.cpp @@ -1036,7 +1036,7 @@ void QJsonObject::setValueAt(int i, const QJsonValue &val) insert(e->key(), val); } -#ifndef QT_NO_DEBUG_STREAM +#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY) QDebug operator<<(QDebug dbg, const QJsonObject &o) { if (!o.o) { diff --git a/src/corelib/json/qjsonobject.h b/src/corelib/json/qjsonobject.h index 8226b614b4..ad3184b1f2 100644 --- a/src/corelib/json/qjsonobject.h +++ b/src/corelib/json/qjsonobject.h @@ -206,7 +206,7 @@ private: QJsonPrivate::Object *o; }; -#ifndef QT_NO_DEBUG_STREAM +#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY) Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonObject &); #endif diff --git a/src/corelib/json/qjsonvalue.cpp b/src/corelib/json/qjsonvalue.cpp index 8aa1f654c6..0a603b958a 100644 --- a/src/corelib/json/qjsonvalue.cpp +++ b/src/corelib/json/qjsonvalue.cpp @@ -661,7 +661,7 @@ QJsonValue QJsonValueRef::toValue() const return o->valueAt(index); } -#ifndef QT_NO_DEBUG_STREAM +#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY) QDebug operator<<(QDebug dbg, const QJsonValue &o) { switch (o.t) { diff --git a/src/corelib/json/qjsonvalue.h b/src/corelib/json/qjsonvalue.h index b18bbde0f7..c0ecdd2b61 100644 --- a/src/corelib/json/qjsonvalue.h +++ b/src/corelib/json/qjsonvalue.h @@ -179,7 +179,7 @@ private: uint index : 31; }; -#ifndef QT_NO_DEBUG_STREAM +#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY) Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonValue &); #endif diff --git a/tests/auto/tools/qmake/testdata/json/json.pro b/tests/auto/tools/qmake/testdata/json/json.pro new file mode 100644 index 0000000000..33440b3209 --- /dev/null +++ b/tests/auto/tools/qmake/testdata/json/json.pro @@ -0,0 +1,26 @@ +jsontext = $$cat($$PWD/test.json) +parseJson(jsontext, json) + +# print all keys +message(json._KEYS_ $${json._KEYS_}) + +# print array +message(json.array._KEYS_ $${json.array._KEYS_}) +for(key, json.array._KEYS_): \ + message(json.array.$${key} $$eval(json.array.$${key})) + +# print object +message(json.object._KEYS_ $${json.object._KEYS_}) +for(key, json.object._KEYS_): \ + message(json.object.$${key} $$eval(json.object.$${key})) + +# print value tyes +message(json.string: $${json.string}) +message(json.number: $${json.number}) +message(json.true: $${json.true}) +message(json.false: $${json.false}) +message(json.null: $${json.null}) + +# check that booleans work +$${json.true}: message(json.true is true) +!$${json.false}: message(json.false is false) diff --git a/tests/auto/tools/qmake/testdata/json/test.json b/tests/auto/tools/qmake/testdata/json/test.json new file mode 100644 index 0000000000..cc82908eba --- /dev/null +++ b/tests/auto/tools/qmake/testdata/json/test.json @@ -0,0 +1,9 @@ +{ + "array" : ["arrayItem1", "arrayItem2", "arrayItem3"], + "object" : { "key1" : "objectValue1", "key2" : "objectValue2" }, + "string" : "test string", + "number" : 999, + "true" : true, + "false" :false, + "null" : null +} diff --git a/tests/auto/tools/qmake/tst_qmake.cpp b/tests/auto/tools/qmake/tst_qmake.cpp index cf5c75a66b..87e86406b8 100644 --- a/tests/auto/tools/qmake/tst_qmake.cpp +++ b/tests/auto/tools/qmake/tst_qmake.cpp @@ -92,6 +92,7 @@ private slots: void substitutes(); void project(); void proFileCache(); + void json(); private: TestCompiler test_compiler; @@ -556,5 +557,33 @@ void tst_qmake::proFileCache() QVERIFY( test_compiler.qmake( workDir, "pro_file_cache" )); } +void tst_qmake::json() +{ + QString workDir = base_path + "/testdata/json"; + QVERIFY( test_compiler.qmake( workDir, "json.pro" )); + QString output = test_compiler.commandOutput(); + + // all keys + QVERIFY(output.contains("json._KEYS_ array false null number object string true")); + // array + QVERIFY(output.contains("json.array._KEYS_ 0 1 2")); + QVERIFY(output.contains("json.array.0 arrayItem1")); + QVERIFY(output.contains("json.array.1 arrayItem2")); + QVERIFY(output.contains("json.array.2 arrayItem3")); + // object + QVERIFY(output.contains("json.object._KEYS_ key1 key2")); + QVERIFY(output.contains("json.object.key1 objectValue1")); + QVERIFY(output.contains("json.object.key1 objectValue1")); + // value types + QVERIFY(output.contains("json.string: test string")); + QVERIFY(output.contains("json.number: 999")); + QVERIFY(output.contains("json.true: true")); + QVERIFY(output.contains("json.false: false")); + QVERIFY(output.contains("json.null:")); + // functional booleans + QVERIFY(output.contains("json.true is true")); + QVERIFY(output.contains("json.false is false")); +} + QTEST_MAIN(tst_qmake) #include "tst_qmake.moc" -- cgit v1.2.3 From e8853506bf82e569009e68a23437d6a134176f63 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 1 Oct 2013 16:05:21 -0700 Subject: Add support for disabling exceptions with ICC Change-Id: Id1ea1bda14a20e44af1eb9f53bae877a3b9fd2e4 Reviewed-by: Olivier Goffart Reviewed-by: Lars Knoll --- mkspecs/linux-icc/qmake.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/mkspecs/linux-icc/qmake.conf b/mkspecs/linux-icc/qmake.conf index 4d51ffb269..7876ef1c34 100644 --- a/mkspecs/linux-icc/qmake.conf +++ b/mkspecs/linux-icc/qmake.conf @@ -42,6 +42,7 @@ QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB QMAKE_CXXFLAGS_STATIC_LIB = $$QMAKE_CFLAGS_STATIC_LIB QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD +QMAKE_CXXFLAGS_EXCEPTIONS_OFF = -fno-exceptions QMAKE_CXXFLAGS_CXX11 = -std=c++0x QMAKE_INCDIR = -- cgit v1.2.3 From add2bf739ae96603cb919b908cbb53c00d0628cc Mon Sep 17 00:00:00 2001 From: Kurt Pattyn Date: Sun, 6 Oct 2013 11:40:47 +0200 Subject: Allow non-character codes in utf8 strings Changed the processing of non-character code handling in the UTF8 codec. Non-character codes are now accepted in QStrings, QUrls and QJson strings. Unit tests were adapted accordingly. For more info about non-character codes, see: http://www.unicode.org/versions/corrigendum9.html [ChangeLog][QtCore][QUtf8] UTF-8 now accepts non-character unicode points; these are not replaced by the replacement character anymore [ChangeLog][QtCore][QUrl] QUrl now fully accepts non-character unicode points; they are encoded as percent characters; they can also be pretty decoded [ChangeLog][QtCore][QJson] The Writer and the Parser now fully accept non-character unicode points. Change-Id: I77cf4f0e6210741eac8082912a0b6118eced4f77 Task-number: QTBUG-33229 Reviewed-by: Lars Knoll Reviewed-by: Thiago Macieira --- src/corelib/codecs/qutfcodec.cpp | 13 +----- src/corelib/io/qurlrecode.cpp | 2 +- src/corelib/json/qjsonparser.cpp | 2 +- src/corelib/json/qjsonwriter.cpp | 7 --- .../corelib/codecs/qtextcodec/tst_qtextcodec.cpp | 54 +++++++++++----------- tests/auto/corelib/codecs/utf8/tst_utf8.cpp | 20 ++++---- tests/auto/corelib/codecs/utf8/utf8data.cpp | 4 +- .../corelib/io/qurlinternal/tst_qurlinternal.cpp | 7 ++- tests/auto/corelib/json/tst_qtjson.cpp | 24 ++++++++-- .../sax/qxmlsimplereader/tst_qxmlsimplereader.cpp | 21 ++------- .../qxmlsimplereader/xmldocs/not-wf/sa/170.xml.ref | 2 +- tests/benchmarks/corelib/tools/qstring/main.cpp | 18 ++++---- 12 files changed, 78 insertions(+), 96 deletions(-) diff --git a/src/corelib/codecs/qutfcodec.cpp b/src/corelib/codecs/qutfcodec.cpp index aeedcf1aa1..e425f8634c 100644 --- a/src/corelib/codecs/qutfcodec.cpp +++ b/src/corelib/codecs/qutfcodec.cpp @@ -106,14 +106,6 @@ QByteArray QUtf8::convertFromUnicode(const QChar *uc, int len, QTextCodec::Conve if (u < 0x0800) { *cursor++ = 0xc0 | ((uchar) (u >> 6)); } else { - // is it one of the Unicode non-characters? - if (QChar::isNonCharacter(u)) { - *cursor++ = replacement; - ++ch; - ++invalid; - continue; - } - if (QChar::requiresSurrogates(u)) { *cursor++ = 0xf0 | ((uchar) (u >> 18)); *cursor++ = 0x80 | (((uchar) (u >> 12)) & 0x3f); @@ -180,15 +172,14 @@ QString QUtf8::convertToUnicode(const char *chars, int len, QTextCodec::Converte --need; if (!need) { // utf-8 bom composes into 0xfeff code point - bool nonCharacter; if (!headerdone && uc == 0xfeff) { // don't do anything, just skip the BOM - } else if (!(nonCharacter = QChar::isNonCharacter(uc)) && QChar::requiresSurrogates(uc) && uc <= QChar::LastValidCodePoint) { + } else if (QChar::requiresSurrogates(uc) && uc <= QChar::LastValidCodePoint) { // surrogate pair Q_ASSERT((qch - (ushort*)result.unicode()) + 2 < result.length()); *qch++ = QChar::highSurrogate(uc); *qch++ = QChar::lowSurrogate(uc); - } else if ((uc < min_uc) || QChar::isSurrogate(uc) || nonCharacter || uc > QChar::LastValidCodePoint) { + } else if ((uc < min_uc) || QChar::isSurrogate(uc) || uc > QChar::LastValidCodePoint) { // error: overlong sequence, UTF16 surrogate or non-character *qch++ = replacement; ++invalid; diff --git a/src/corelib/io/qurlrecode.cpp b/src/corelib/io/qurlrecode.cpp index 7e77b9c251..ba1a77744c 100644 --- a/src/corelib/io/qurlrecode.cpp +++ b/src/corelib/io/qurlrecode.cpp @@ -304,7 +304,7 @@ static bool encodedUtf8ToUtf16(QString &result, ushort *&output, const ushort *b // we've decoded something; safety-check it if (uc < min_uc) return false; - if (QChar::isSurrogate(uc) || QChar::isNonCharacter(uc) || uc > QChar::LastValidCodePoint) + if (QChar::isSurrogate(uc) || uc > QChar::LastValidCodePoint) return false; if (!QChar::requiresSurrogates(uc)) { diff --git a/src/corelib/json/qjsonparser.cpp b/src/corelib/json/qjsonparser.cpp index 8721f06064..516c53775c 100644 --- a/src/corelib/json/qjsonparser.cpp +++ b/src/corelib/json/qjsonparser.cpp @@ -853,7 +853,7 @@ static inline bool scanUtf8Char(const char *&json, const char *end, uint *result uc = (uc << 6) | (ch & 0x3f); } - if (uc < min_uc || QChar::isNonCharacter(uc) || + if (uc < min_uc || QChar::isSurrogate(uc) || uc > QChar::LastValidCodePoint) { return false; } diff --git a/src/corelib/json/qjsonwriter.cpp b/src/corelib/json/qjsonwriter.cpp index 8426b351f6..86cca4bb26 100644 --- a/src/corelib/json/qjsonwriter.cpp +++ b/src/corelib/json/qjsonwriter.cpp @@ -138,13 +138,6 @@ static QByteArray escapedString(const QString &s) if (u < 0x0800) { *cursor++ = 0xc0 | ((uchar) (u >> 6)); } else { - // is it one of the Unicode non-characters? - if (QChar::isNonCharacter(u)) { - *cursor++ = replacement; - ++ch; - continue; - } - if (QChar::requiresSurrogates(u)) { *cursor++ = 0xf0 | ((uchar) (u >> 18)); *cursor++ = 0x80 | (((uchar) (u >> 12)) & 0x3f); diff --git a/tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp b/tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp index dd557b8d21..8e1b3cf3b2 100644 --- a/tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp +++ b/tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp @@ -66,9 +66,9 @@ private slots: void codecForLocale(); void asciiToIscii() const; - void flagCodepointFFFF() const; + void nonFlaggedCodepointFFFF() const; void flagF7808080() const; - void flagEFBFBF() const; + void nonFlaggedEFBFBF() const; void decode0D() const; void aliasForUTF16() const; void mibForTSCII() const; @@ -409,9 +409,9 @@ void tst_QTextCodec::asciiToIscii() const } } -void tst_QTextCodec::flagCodepointFFFF() const +void tst_QTextCodec::nonFlaggedCodepointFFFF() const { - // This is an invalid Unicode codepoint. + //Check that the code point 0xFFFF (=non-character code 0xEFBFBF) is not flagged const QChar ch(0xFFFF); QString input(ch); @@ -419,12 +419,11 @@ void tst_QTextCodec::flagCodepointFFFF() const QVERIFY(codec); const QByteArray asDecoded(codec->fromUnicode(input)); - QCOMPARE(asDecoded, QByteArray("?")); + QCOMPARE(asDecoded, QByteArray("\357\277\277")); QByteArray ffff("\357\277\277"); QTextCodec::ConverterState state(QTextCodec::ConvertInvalidToNull); - QVERIFY(codec->toUnicode(ffff.constData(), ffff.length(), &state) == QChar(0)); - QVERIFY(codec->toUnicode(ffff) == QChar(0xfffd)); + QVERIFY(codec->toUnicode(ffff.constData(), ffff.length(), &state) == QByteArray::fromHex("EFBFBF")); } void tst_QTextCodec::flagF7808080() const @@ -460,13 +459,16 @@ void tst_QTextCodec::flagF7808080() const QVERIFY(codec->toUnicode(input.constData(), input.length(), &state) == QChar(0)); } -void tst_QTextCodec::flagEFBFBF() const +void tst_QTextCodec::nonFlaggedEFBFBF() const { - QByteArray invalidInput; - invalidInput.resize(3); - invalidInput[0] = char(0xEF); - invalidInput[1] = char(0xBF); - invalidInput[2] = char(0xBF); + /* Check that the codec does NOT flag EFBFBF. + * This is a regression test; see QTBUG-33229 + */ + QByteArray validInput; + validInput.resize(3); + validInput[0] = char(0xEF); + validInput[1] = char(0xBF); + validInput[2] = char(0xBF); const QTextCodec *const codec = QTextCodec::codecForMib(106); // UTF-8 QVERIFY(codec); @@ -474,21 +476,20 @@ void tst_QTextCodec::flagEFBFBF() const { //QVERIFY(!codec->canEncode(QChar(0xFFFF))); QTextCodec::ConverterState state(QTextCodec::ConvertInvalidToNull); - QVERIFY(codec->toUnicode(invalidInput.constData(), invalidInput.length(), &state) == QChar(0)); + QVERIFY(codec->toUnicode(validInput.constData(), validInput.length(), &state) == QByteArray::fromHex("EFBFBF")); QByteArray start(""); } - /* When 0xEFBFBF is preceded by what seems to be an arbitrary character, - * QTextCodec fails to flag it. */ + // Check that 0xEFBFBF is correctly decoded when preceded by an arbitrary character { QByteArray start("B"); - start.append(invalidInput); + start.append(validInput); QTextCodec::ConverterState state(QTextCodec::ConvertInvalidToNull); - QVERIFY(codec->toUnicode(start.constData(), start.length(), &state) == QString::fromLatin1("B\0", 2)); + QVERIFY(codec->toUnicode(start.constData(), start.length(), &state) == QByteArray("B").append(QByteArray::fromHex("EFBFBF"))); } } @@ -674,13 +675,12 @@ void tst_QTextCodec::utf8Codec_data() str = QChar(0x7ff); QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.2.2") << utf8 << str << -1; - // 2.2.3 U+000FFFF + // 2.2.3 U+000FFFF - non-character code utf8.clear(); utf8 += char(0xef); utf8 += char(0xbf); utf8 += char(0xbf); - str.clear(); - str += QChar::ReplacementCharacter; + str = QString::fromUtf8(utf8); QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.2.3") << utf8 << str << -1; // 2.2.4 U+001FFFFF @@ -1535,20 +1535,22 @@ void tst_QTextCodec::utf8Codec_data() str += QChar(QChar::ReplacementCharacter); QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.2.8") << utf8 << str << -1; - // 5.3.1 + // 5.3.1 - non-character code utf8.clear(); utf8 += char(0xef); utf8 += char(0xbf); utf8 += char(0xbe); - str = QChar(QChar::ReplacementCharacter); + //str = QChar(QChar::ReplacementCharacter); + str = QString::fromUtf8(utf8); QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.3.1") << utf8 << str << -1; - // 5.3.2 + // 5.3.2 - non-character code utf8.clear(); utf8 += char(0xef); utf8 += char(0xbf); utf8 += char(0xbf); - str = QChar(QChar::ReplacementCharacter); + //str = QChar(QChar::ReplacementCharacter); + str = QString::fromUtf8(utf8); QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.3.2") << utf8 << str << -1; } diff --git a/tests/auto/corelib/codecs/utf8/tst_utf8.cpp b/tests/auto/corelib/codecs/utf8/tst_utf8.cpp index 99147f3aff..e18f6f73b9 100644 --- a/tests/auto/corelib/codecs/utf8/tst_utf8.cpp +++ b/tests/auto/corelib/codecs/utf8/tst_utf8.cpp @@ -233,8 +233,9 @@ void tst_Utf8::nonCharacters_data() QTest::addColumn("utf8"); QTest::addColumn("utf16"); - // Unicode has a couple of "non-characters" that one can use internally, - // but are not allowed to be used for text interchange. + // Unicode has a couple of "non-characters" that one can use internally + // These characters may be used for interchange; + // see: http://www.unicode.org/versions/corrigendum9.html // // Those are the last two entries each Unicode Plane (U+FFFE, U+FFFF, // U+1FFFE, U+1FFFF, etc.) as well as the entries between U+FDD0 and @@ -279,20 +280,17 @@ void tst_Utf8::nonCharacters() decoder->toUnicode(utf8); // Only enforce correctness on our UTF-8 decoder - // The system's UTF-8 codec is sometimes buggy - // GNU libc's iconv is known to accept U+FFFF and U+FFFE encoded as UTF-8 - // OS X's iconv is known to accept those, plus surrogates and codepoints above U+10FFFF if (!useLocale) - QVERIFY(decoder->hasFailure()); - else if (!decoder->hasFailure()) - qWarning("System codec does not report failure when it should. Should report bug upstream."); + QVERIFY(!decoder->hasFailure()); + else if (decoder->hasFailure()) + qWarning("System codec reports failure when it shouldn't. Should report bug upstream."); QSharedPointer encoder(codec->makeEncoder()); encoder->fromUnicode(utf16); if (!useLocale) - QVERIFY(encoder->hasFailure()); - else if (!encoder->hasFailure()) - qWarning("System codec does not report failure when it should. Should report bug upstream."); + QVERIFY(!encoder->hasFailure()); + else if (encoder->hasFailure()) + qWarning("System codec reports failure when it shouldn't. Should report bug upstream."); } QTEST_MAIN(tst_Utf8) diff --git a/tests/auto/corelib/codecs/utf8/utf8data.cpp b/tests/auto/corelib/codecs/utf8/utf8data.cpp index 2516cc9734..a41b0772e6 100644 --- a/tests/auto/corelib/codecs/utf8/utf8data.cpp +++ b/tests/auto/corelib/codecs/utf8/utf8data.cpp @@ -129,8 +129,8 @@ void loadInvalidUtf8Rows() void loadNonCharactersRows() { - // Unicode has a couple of "non-characters" that one can use internally, - // but are not allowed to be used for text interchange. + // Unicode has a couple of "non-characters" that one can use internally + // These characters are allowed for text-interchange (see http://www.unicode.org/versions/corrigendum9.html) // // Those are the last two entries each Unicode Plane (U+FFFE, U+FFFF, // U+1FFFE, U+1FFFF, etc.) as well as the entries between U+FDD0 and diff --git a/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp b/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp index 75b17df759..d3a8bcfd13 100644 --- a/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp +++ b/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp @@ -964,8 +964,10 @@ void tst_QUrlInternal::encodingRecode_data() addUtf8Data("utf8-string-2", "\xDF\xBF\xE0\xA0\x80""A"); addUtf8Data("utf8-string-3", "\xE0\xA0\x80\xDF\xBF..."); + QTest::newRow("encode-unicode-noncharacter") << QString(QChar(0xffff)) << F(QUrl::FullyEncoded) << "%EF%BF%BF"; + QTest::newRow("decode-unicode-noncharacter") << QString(QChar(0xffff)) << F(QUrl::PrettyDecoded) << QString::fromUtf8("\xEF\xBF\xBF"); + // special cases: stuff we can encode, but not decode - QTest::newRow("unicode-noncharacter") << QString(QChar(0xffff)) << F(QUrl::FullyEncoded) << "%EF%BF%BF"; QTest::newRow("unicode-lo-surrogate") << QString(QChar(0xD800)) << F(QUrl::FullyEncoded) << "%ED%A0%80"; QTest::newRow("unicode-hi-surrogate") << QString(QChar(0xDC00)) << F(QUrl::FullyEncoded) << "%ED%B0%80"; @@ -1011,9 +1013,6 @@ void tst_QUrlInternal::encodingRecodeInvalidUtf8_data() extern void loadInvalidUtf8Rows(); loadInvalidUtf8Rows(); - extern void loadNonCharactersRows(); - loadNonCharactersRows(); - QTest::newRow("utf8-mix-4") << QByteArray("\xE0.A2\x80"); QTest::newRow("utf8-mix-5") << QByteArray("\xE0\xA2.80"); QTest::newRow("utf8-mix-6") << QByteArray("\xE0\xA2\x33"); diff --git a/tests/auto/corelib/json/tst_qtjson.cpp b/tests/auto/corelib/json/tst_qtjson.cpp index 9dbd6414ad..c79e7273c0 100644 --- a/tests/auto/corelib/json/tst_qtjson.cpp +++ b/tests/auto/corelib/json/tst_qtjson.cpp @@ -47,7 +47,8 @@ #include "qjsondocument.h" #include -#define INVALID_UNICODE "\357\277\277" // "\uffff" +#define INVALID_UNICODE "\xCE\xBA\xE1" +#define UNICODE_NON_CHARACTER "\xEF\xBF\xBF" #define UNICODE_DJE "\320\202" // Character from the Serbian Cyrillic alphabet class tst_QtJson: public QObject @@ -1305,6 +1306,19 @@ void tst_QtJson::fromJson() QCOMPARE(array.at(0).toBool(), true); QCOMPARE(doc.toJson(), json); } + { + //regression test: test if unicode_control_characters are correctly decoded + QByteArray json = "[\n \"" UNICODE_NON_CHARACTER "\"\n]\n"; + QJsonDocument doc = QJsonDocument::fromJson(json); + QVERIFY(!doc.isEmpty()); + QCOMPARE(doc.isArray(), true); + QCOMPARE(doc.isObject(), false); + QJsonArray array = doc.array(); + QCOMPARE(array.size(), 1); + QCOMPARE(array.at(0).type(), QJsonValue::String); + QCOMPARE(array.at(0).toString(), QString::fromUtf8(UNICODE_NON_CHARACTER)); + QCOMPARE(doc.toJson(), json); + } { QByteArray json = "[]"; QJsonDocument doc = QJsonDocument::fromJson(json); @@ -1532,7 +1546,7 @@ void tst_QtJson::fromJsonErrors() QJsonDocument doc = QJsonDocument::fromJson(json, &error); QVERIFY(doc.isEmpty()); QCOMPARE(error.error, QJsonParseError::IllegalUTF8String); - QCOMPARE(error.offset, 13); + QCOMPARE(error.offset, 14); } { QJsonParseError error; @@ -1556,7 +1570,7 @@ void tst_QtJson::fromJsonErrors() QJsonDocument doc = QJsonDocument::fromJson(json, &error); QVERIFY(doc.isEmpty()); QCOMPARE(error.error, QJsonParseError::IllegalUTF8String); - QCOMPARE(error.offset, 14); + QCOMPARE(error.offset, 15); } { QJsonParseError error; @@ -1702,6 +1716,7 @@ void tst_QtJson::parseStrings() "abc\\tabc", "abc\\u0019abc", "abc" UNICODE_DJE "abc", + UNICODE_NON_CHARACTER }; int size = sizeof(strings)/sizeof(const char *); @@ -1728,7 +1743,8 @@ void tst_QtJson::parseStrings() Pairs pairs [] = { { "abc\\/abc", "abc/abc" }, { "abc\\u0402abc", "abc" UNICODE_DJE "abc" }, - { "abc\\u0065abc", "abceabc" } + { "abc\\u0065abc", "abceabc" }, + { "abc\\uFFFFabc", "abc" UNICODE_NON_CHARACTER "abc" } }; size = sizeof(pairs)/sizeof(Pairs); diff --git a/tests/auto/xml/sax/qxmlsimplereader/tst_qxmlsimplereader.cpp b/tests/auto/xml/sax/qxmlsimplereader/tst_qxmlsimplereader.cpp index d4c0ff44ca..5be43e2c8f 100644 --- a/tests/auto/xml/sax/qxmlsimplereader/tst_qxmlsimplereader.cpp +++ b/tests/auto/xml/sax/qxmlsimplereader/tst_qxmlsimplereader.cpp @@ -315,8 +315,6 @@ void tst_QXmlSimpleReader::testGoodXmlFile() QVERIFY(file.open(QIODevice::ReadOnly)); Parser parser; -// static int i = 0; -// qWarning("Test nr: " + QString::number(i)); ++i; QEXPECT_FAIL("xmldocs/valid/sa/089.xml", "", Continue); QVERIFY(parser.parseFile(&file)); @@ -326,7 +324,6 @@ void tst_QXmlSimpleReader::testGoodXmlFile() ref_stream.setCodec("UTF-8"); QString ref_file_contents = ref_stream.readAll(); - QEXPECT_FAIL("xmldocs/valid/sa/089.xml", "", Continue); QCOMPARE(parser.result(), ref_file_contents); } @@ -355,8 +352,6 @@ void tst_QXmlSimpleReader::testBadXmlFile() QVERIFY(file.open(QIODevice::ReadOnly)); Parser parser; -// static int i = 0; -// qWarning("Test nr: " + QString::number(++i)); QEXPECT_FAIL("xmldocs/not-wf/sa/030.xml", "", Continue); QEXPECT_FAIL("xmldocs/not-wf/sa/031.xml", "", Continue); QEXPECT_FAIL("xmldocs/not-wf/sa/032.xml", "", Continue); @@ -381,22 +376,17 @@ void tst_QXmlSimpleReader::testBadXmlFile() QEXPECT_FAIL("xmldocs/not-wf/sa/132.xml", "", Continue); QEXPECT_FAIL("xmldocs/not-wf/sa/142.xml", "", Continue); QEXPECT_FAIL("xmldocs/not-wf/sa/143.xml", "", Continue); + QEXPECT_FAIL("xmldocs/not-wf/sa/144.xml", "", Continue); QEXPECT_FAIL("xmldocs/not-wf/sa/145.xml", "", Continue); QEXPECT_FAIL("xmldocs/not-wf/sa/146.xml", "", Abort); QEXPECT_FAIL("xmldocs/not-wf/sa/160.xml", "", Continue); QEXPECT_FAIL("xmldocs/not-wf/sa/162.xml", "", Continue); - QEXPECT_FAIL("xmldocs/not-wf/sa/166.xml", "", Continue); - QEXPECT_FAIL("xmldocs/not-wf/sa/167.xml", "", Continue); + QEXPECT_FAIL("xmldocs/not-wf/sa/168.xml", "", Continue); QEXPECT_FAIL("xmldocs/not-wf/sa/169.xml", "", Continue); QEXPECT_FAIL("xmldocs/not-wf/sa/170.xml", "", Continue); - QEXPECT_FAIL("xmldocs/not-wf/sa/171.xml", "", Abort); - QEXPECT_FAIL("xmldocs/not-wf/sa/172.xml", "", Abort); - QEXPECT_FAIL("xmldocs/not-wf/sa/173.xml", "", Abort); - QEXPECT_FAIL("xmldocs/not-wf/sa/174.xml", "", Abort); - QEXPECT_FAIL("xmldocs/not-wf/sa/175.xml", "", Abort); - QEXPECT_FAIL("xmldocs/not-wf/sa/177.xml", "", Abort); + QEXPECT_FAIL("xmldocs/not-wf/sa/180.xml", "", Continue); QEXPECT_FAIL("xmldocs/not-wf/sa/181.xml", "", Continue); QEXPECT_FAIL("xmldocs/not-wf/sa/182.xml", "", Continue); @@ -411,12 +401,7 @@ void tst_QXmlSimpleReader::testBadXmlFile() ref_stream.setCodec("UTF-8"); QString ref_file_contents = ref_stream.readAll(); - QEXPECT_FAIL("xmldocs/not-wf/sa/144.xml", "", Continue); QEXPECT_FAIL("xmldocs/not-wf/sa/145.xml", "", Continue); - QEXPECT_FAIL("xmldocs/not-wf/sa/146.xml", "", Continue); - QEXPECT_FAIL("xmldocs/not-wf/sa/167.xml", "", Continue); - QEXPECT_FAIL("xmldocs/not-wf/sa/166.xml", "", Continue); - QEXPECT_FAIL("xmldocs/not-wf/sa/170.xml", "", Continue); QCOMPARE(parser.result(), ref_file_contents); } diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/not-wf/sa/170.xml.ref b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/not-wf/sa/170.xml.ref index 0508ee88c7..eca786f688 100644 --- a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/not-wf/sa/170.xml.ref +++ b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/not-wf/sa/170.xml.ref @@ -1,6 +1,6 @@ setDocumentLocator(locator={columnNumber=1, lineNumber=1}) startDocument() startElement(namespaceURI="", localName="doc", qName="doc", atts=[]) - characters(ch="í»€í°€") + characters(ch="�") endElement(namespaceURI="", localName="doc", qName="doc") endDocument() diff --git a/tests/benchmarks/corelib/tools/qstring/main.cpp b/tests/benchmarks/corelib/tools/qstring/main.cpp index 67ed4c32b9..6101cfe8fb 100644 --- a/tests/benchmarks/corelib/tools/qstring/main.cpp +++ b/tests/benchmarks/corelib/tools/qstring/main.cpp @@ -1980,16 +1980,15 @@ int fromUtf8_qt47(ushort *dst, const char *chars, int len) --need; if (!need) { // utf-8 bom composes into 0xfeff code point - bool nonCharacter; if (!headerdone && uc == 0xfeff) { // don't do anything, just skip the BOM - } else if (!(nonCharacter = QChar::isNonCharacter(uc)) && QChar::requiresSurrogates(uc) && uc <= QChar::LastValidCodePoint) { + } else if (QChar::requiresSurrogates(uc) && uc <= QChar::LastValidCodePoint) { // surrogate pair //Q_ASSERT((qch - (ushort*)result.unicode()) + 2 < result.length()); *qch++ = QChar::highSurrogate(uc); *qch++ = QChar::lowSurrogate(uc); - } else if ((uc < min_uc) || QChar::isSurrogate(uc) || nonCharacter || uc > QChar::LastValidCodePoint) { - // error: overlong sequence, UTF16 surrogate or non-character + } else if ((uc < min_uc) || QChar::isSurrogate(uc) || uc > QChar::LastValidCodePoint) { + // error: overlong sequence or UTF16 surrogate *qch++ = replacement; ++invalid; } else { @@ -2086,16 +2085,15 @@ int fromUtf8_qt47_stateless(ushort *dst, const char *chars, int len) --need; if (!need) { // utf-8 bom composes into 0xfeff code point - bool nonCharacter; if (!headerdone && uc == 0xfeff) { // don't do anything, just skip the BOM - } else if (!(nonCharacter = QChar::isNonCharacter(uc)) && QChar::requiresSurrogates(uc) && uc <= QChar::LastValidCodePoint) { + } else if (QChar::requiresSurrogates(uc) && uc <= QChar::LastValidCodePoint) { // surrogate pair //Q_ASSERT((qch - (ushort*)result.unicode()) + 2 < result.length()); *qch++ = QChar::highSurrogate(uc); *qch++ = QChar::lowSurrogate(uc); - } else if ((uc < min_uc) || QChar::isSurrogate(uc) || nonCharacter || uc > QChar::LastValidCodePoint) { - // error: overlong sequence, UTF16 surrogate or non-character + } else if ((uc < min_uc) || QChar::isSurrogate(uc) || uc > QChar::LastValidCodePoint) { + // error: overlong sequence or UTF16 surrogate *qch++ = replacement; ++invalid; } else { @@ -2214,7 +2212,7 @@ static inline void extract_utf8_multibyte(ushort *&dst, const char *&chars, qptr chars += 2; len -= 2; if (!trusted && - (ucs < 0x800 || QChar::isNonCharacter(ucs) || QChar::isSurrogate(ucs))) + (ucs < 0x800 || QChar::isSurrogate(ucs))) dst[counter] = QChar::ReplacementCharacter; else dst[counter] = ucs; @@ -2245,7 +2243,7 @@ static inline void extract_utf8_multibyte(ushort *&dst, const char *&chars, qptr // dst[counter] will correspond to chars[counter..counter+2], so adjust chars += 3; len -= 3; - if (trusted || (QChar::requiresSurrogates(ucs) && ucs <= QChar::LastValidCodePoint && !QChar::isNonCharacter(ucs))) { + if (trusted || (QChar::requiresSurrogates(ucs) && ucs <= QChar::LastValidCodePoint)) { dst[counter + 0] = QChar::highSurrogate(ucs); dst[counter + 1] = QChar::lowSurrogate(ucs); counter += 2; -- cgit v1.2.3 From 69cd7e8f7001b58939055bf75066b2c439233b0e Mon Sep 17 00:00:00 2001 From: Kurt Pattyn Date: Sun, 13 Oct 2013 20:14:20 +0200 Subject: Clarify that the URL scheme does not include the ':' From the documentation of setScheme it was not clear if the scheme should be terminated by a ':' or not. Documentation has been updated to clarify the expected syntax for the scheme. Change-Id: Ied8533beef7daa12e1d5e7da0649c184efb84522 Reviewed-by: David Faure Reviewed-by: Thiago Macieira --- src/corelib/io/qurl.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index 6b7c5bde2d..fe5faa2be7 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -1840,12 +1840,21 @@ void QUrl::setUrl(const QString &url, ParsingMode parsingMode) input. It must also start with an ASCII letter. The scheme describes the type (or protocol) of the URL. It's - represented by one or more ASCII characters at the start the URL, - and is followed by a ':'. The following example shows a URL where - the scheme is "ftp": + represented by one or more ASCII characters at the start the URL. + + A scheme is strictly \l {http://www.ietf.org/rfc/rfc3986.txt} {RFC 3986}-compliant: + \tt {scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )} + + The following example shows a URL where the scheme is "ftp": \image qurl-authority2.png + To set the scheme, the following call is used: + \code + QUrl url; + url.setScheme("ftp"); + \endcode + The scheme can also be empty, in which case the URL is interpreted as relative. @@ -3327,7 +3336,7 @@ QString QUrl::fromPercentEncoding(const QByteArray &input) them to \a include. Unreserved is defined as: - ALPHA / DIGIT / "-" / "." / "_" / "~" + \tt {ALPHA / DIGIT / "-" / "." / "_" / "~"} \snippet code/src_corelib_io_qurl.cpp 6 */ -- cgit v1.2.3 From 979a55a1ef3f5d7402b76f5fe50e59315b24de25 Mon Sep 17 00:00:00 2001 From: Kurt Pattyn Date: Sat, 12 Oct 2013 19:02:21 +0200 Subject: Add explanation to QEXPECT_FAIL statements Added clarifying explanations to the QEXPECT_FAIL statements. Now it should be easier to understand what is expected from the parser. Change-Id: I1dacd60564f292d9ce43de7254525c34fa7cdc55 Reviewed-by: Thiago Macieira --- .../sax/qxmlsimplereader/tst_qxmlsimplereader.cpp | 84 +++++++++++----------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/tests/auto/xml/sax/qxmlsimplereader/tst_qxmlsimplereader.cpp b/tests/auto/xml/sax/qxmlsimplereader/tst_qxmlsimplereader.cpp index 5be43e2c8f..f09fbff6c4 100644 --- a/tests/auto/xml/sax/qxmlsimplereader/tst_qxmlsimplereader.cpp +++ b/tests/auto/xml/sax/qxmlsimplereader/tst_qxmlsimplereader.cpp @@ -315,7 +315,7 @@ void tst_QXmlSimpleReader::testGoodXmlFile() QVERIFY(file.open(QIODevice::ReadOnly)); Parser parser; - QEXPECT_FAIL("xmldocs/valid/sa/089.xml", "", Continue); + QEXPECT_FAIL("xmldocs/valid/sa/089.xml", "a form feed character is not accepted in XML", Continue); QVERIFY(parser.parseFile(&file)); QFile ref_file(file_name + ".ref"); @@ -352,46 +352,46 @@ void tst_QXmlSimpleReader::testBadXmlFile() QVERIFY(file.open(QIODevice::ReadOnly)); Parser parser; - QEXPECT_FAIL("xmldocs/not-wf/sa/030.xml", "", Continue); - QEXPECT_FAIL("xmldocs/not-wf/sa/031.xml", "", Continue); - QEXPECT_FAIL("xmldocs/not-wf/sa/032.xml", "", Continue); - QEXPECT_FAIL("xmldocs/not-wf/sa/033.xml", "", Continue); - QEXPECT_FAIL("xmldocs/not-wf/sa/038.xml", "", Continue); - QEXPECT_FAIL("xmldocs/not-wf/sa/072.xml", "", Continue); - QEXPECT_FAIL("xmldocs/not-wf/sa/073.xml", "", Continue); - QEXPECT_FAIL("xmldocs/not-wf/sa/074.xml", "", Continue); - QEXPECT_FAIL("xmldocs/not-wf/sa/076.xml", "", Continue); - QEXPECT_FAIL("xmldocs/not-wf/sa/077.xml", "", Continue); - QEXPECT_FAIL("xmldocs/not-wf/sa/078.xml", "", Continue); - QEXPECT_FAIL("xmldocs/not-wf/sa/085.xml", "", Continue); - QEXPECT_FAIL("xmldocs/not-wf/sa/086.xml", "", Continue); - QEXPECT_FAIL("xmldocs/not-wf/sa/087.xml", "", Continue); - QEXPECT_FAIL("xmldocs/not-wf/sa/101.xml", "", Continue); - QEXPECT_FAIL("xmldocs/not-wf/sa/102.xml", "", Continue); - QEXPECT_FAIL("xmldocs/not-wf/sa/104.xml", "", Continue); - QEXPECT_FAIL("xmldocs/not-wf/sa/116.xml", "", Continue); - QEXPECT_FAIL("xmldocs/not-wf/sa/117.xml", "", Continue); - QEXPECT_FAIL("xmldocs/not-wf/sa/119.xml", "", Continue); - QEXPECT_FAIL("xmldocs/not-wf/sa/122.xml", "", Continue); - QEXPECT_FAIL("xmldocs/not-wf/sa/132.xml", "", Continue); - QEXPECT_FAIL("xmldocs/not-wf/sa/142.xml", "", Continue); - QEXPECT_FAIL("xmldocs/not-wf/sa/143.xml", "", Continue); - - QEXPECT_FAIL("xmldocs/not-wf/sa/144.xml", "", Continue); - QEXPECT_FAIL("xmldocs/not-wf/sa/145.xml", "", Continue); - QEXPECT_FAIL("xmldocs/not-wf/sa/146.xml", "", Abort); - QEXPECT_FAIL("xmldocs/not-wf/sa/160.xml", "", Continue); - QEXPECT_FAIL("xmldocs/not-wf/sa/162.xml", "", Continue); - - QEXPECT_FAIL("xmldocs/not-wf/sa/168.xml", "", Continue); - QEXPECT_FAIL("xmldocs/not-wf/sa/169.xml", "", Continue); - QEXPECT_FAIL("xmldocs/not-wf/sa/170.xml", "", Continue); - - QEXPECT_FAIL("xmldocs/not-wf/sa/180.xml", "", Continue); - QEXPECT_FAIL("xmldocs/not-wf/sa/181.xml", "", Continue); - QEXPECT_FAIL("xmldocs/not-wf/sa/182.xml", "", Continue); - QEXPECT_FAIL("xmldocs/not-wf/sa/185.xml", "", Continue); - QEXPECT_FAIL("xmldocs/not-wf/sa/186.xml", "", Continue); + QEXPECT_FAIL("xmldocs/not-wf/sa/030.xml", "a form feed character is not accepted in XML", Continue); + QEXPECT_FAIL("xmldocs/not-wf/sa/031.xml", "a form feed character is not accepted in a processing instruction", Continue); + QEXPECT_FAIL("xmldocs/not-wf/sa/032.xml", "a form feed character is not accepted in a comment", Continue); + QEXPECT_FAIL("xmldocs/not-wf/sa/033.xml", "overlong sequence - small latin letter d should be rejected", Continue); + QEXPECT_FAIL("xmldocs/not-wf/sa/038.xml", "attribute x redefined; should be rejected", Continue); + QEXPECT_FAIL("xmldocs/not-wf/sa/072.xml", "entity foo not defined", Continue); + QEXPECT_FAIL("xmldocs/not-wf/sa/073.xml", "entity f not defined", Continue); + QEXPECT_FAIL("xmldocs/not-wf/sa/074.xml", "entity e is not well-formed ()", Continue); + QEXPECT_FAIL("xmldocs/not-wf/sa/076.xml", "entity foo is not defined", Continue); + QEXPECT_FAIL("xmldocs/not-wf/sa/077.xml", "entity bar is not defined within the definition of entity foo", Continue); + QEXPECT_FAIL("xmldocs/not-wf/sa/078.xml", "entity foo not defined", Continue); + QEXPECT_FAIL("xmldocs/not-wf/sa/085.xml", "Unfinished Public or System Id", Continue); + QEXPECT_FAIL("xmldocs/not-wf/sa/086.xml", "Unfinished Public or System Id", Continue); + QEXPECT_FAIL("xmldocs/not-wf/sa/087.xml", "Unfinished Public or System Id", Continue); + QEXPECT_FAIL("xmldocs/not-wf/sa/101.xml", "Invalid XML encoding name (space before utf-8)", Continue); + QEXPECT_FAIL("xmldocs/not-wf/sa/102.xml", "Invalid version specification (1.0 followed by space)", Continue); + QEXPECT_FAIL("xmldocs/not-wf/sa/104.xml", "Premature end of data in tag foo", Continue); + QEXPECT_FAIL("xmldocs/not-wf/sa/116.xml", "Invalid decimal value", Continue); + QEXPECT_FAIL("xmldocs/not-wf/sa/117.xml", "No name", Continue); + QEXPECT_FAIL("xmldocs/not-wf/sa/119.xml", "No name", Continue); + QEXPECT_FAIL("xmldocs/not-wf/sa/122.xml", "; expected in declaration of element", Continue); + QEXPECT_FAIL("xmldocs/not-wf/sa/132.xml", "; expected in declaration of element", Continue); + QEXPECT_FAIL("xmldocs/not-wf/sa/142.xml", "Invalid value '0'", Continue); + QEXPECT_FAIL("xmldocs/not-wf/sa/143.xml", "Invalid value '31'", Continue); + + QEXPECT_FAIL("xmldocs/not-wf/sa/144.xml", "noncharacter code 0xFFFF should be rejected", Continue); + QEXPECT_FAIL("xmldocs/not-wf/sa/145.xml", "surrogate code point 0xD800 should be rejected", Continue); + QEXPECT_FAIL("xmldocs/not-wf/sa/146.xml", "code point out-of-range 0x110000 (must be < 0x10FFFE)", Abort); + QEXPECT_FAIL("xmldocs/not-wf/sa/160.xml", "Parameter references forbidden in internal subset", Continue); + QEXPECT_FAIL("xmldocs/not-wf/sa/162.xml", "Parameter references forbidden in internal subset", Continue); + + QEXPECT_FAIL("xmldocs/not-wf/sa/168.xml", "Surrogate code point 0xEDA080 should be rejected", Continue); + QEXPECT_FAIL("xmldocs/not-wf/sa/169.xml", "Surrogate code point 0xEDB080 should be rejected", Continue); + QEXPECT_FAIL("xmldocs/not-wf/sa/170.xml", "Code point 0xF7808080 should be rejected", Continue); + + QEXPECT_FAIL("xmldocs/not-wf/sa/180.xml", "Entity e is not defined", Continue); + QEXPECT_FAIL("xmldocs/not-wf/sa/181.xml", "Unregistered error message", Continue); + QEXPECT_FAIL("xmldocs/not-wf/sa/182.xml", "Comment not terminated", Continue); + QEXPECT_FAIL("xmldocs/not-wf/sa/185.xml", "Entity e not defined", Continue); + QEXPECT_FAIL("xmldocs/not-wf/sa/186.xml", "Attributes constructs error", Continue); QVERIFY(!parser.parseFile(&file)); @@ -401,7 +401,7 @@ void tst_QXmlSimpleReader::testBadXmlFile() ref_stream.setCodec("UTF-8"); QString ref_file_contents = ref_stream.readAll(); - QEXPECT_FAIL("xmldocs/not-wf/sa/145.xml", "", Continue); + QEXPECT_FAIL("xmldocs/not-wf/sa/145.xml", "Surrogate code point 0xD800 should be rejected", Continue); QCOMPARE(parser.result(), ref_file_contents); } -- cgit v1.2.3 From b7b2bdef1525f6b0fbf13f46224d732f41e0575c Mon Sep 17 00:00:00 2001 From: Andy Nichols Date: Wed, 16 Oct 2013 17:25:23 +0200 Subject: linux-rasp-pi: Remove custom cursor code This code was added as an optimization for showing a mouse cursor on the Raspberry Pi. What happens though is while the mouse cursor does move more smoothly, the actual application becomes less smooth when the mouse cursor is moved. By removing the custom cursor code, performance will no longer be effected by rendering a moving mouse cursor. Change-Id: I9f8ac6c236cd4ff6d8e1d999a461c3e6db75d7e3 Reviewed-by: Samuli Piippo Reviewed-by: Laszlo Agocs --- .../devices/linux-rasp-pi-g++/qeglfshooks_pi.cpp | 86 ---------------------- 1 file changed, 86 deletions(-) diff --git a/mkspecs/devices/linux-rasp-pi-g++/qeglfshooks_pi.cpp b/mkspecs/devices/linux-rasp-pi-g++/qeglfshooks_pi.cpp index 671f525250..5e57ba382a 100644 --- a/mkspecs/devices/linux-rasp-pi-g++/qeglfshooks_pi.cpp +++ b/mkspecs/devices/linux-rasp-pi-g++/qeglfshooks_pi.cpp @@ -136,89 +136,6 @@ static void destroyDispmanxLayer(EGLNativeWindowType window) delete eglWindow; } -class QEglFSPiCursor : public QEglFSCursor -{ -public: - QEglFSPiCursor(QEglFSScreen *screen) : QEglFSCursor(screen) { - QSurfaceFormat platformFormat; - platformFormat.setDepthBufferSize(24); - platformFormat.setStencilBufferSize(8); - platformFormat.setRedBufferSize(8); - platformFormat.setGreenBufferSize(8); - platformFormat.setBlueBufferSize(8); - platformFormat.setAlphaBufferSize(8); - m_config = q_configFromGLFormat(m_screen->display(), platformFormat); - - createSurface(); - createContext(); - drawInLayer(); - } - - ~QEglFSPiCursor() { - eglDestroySurface(m_screen->display(), m_surface); - destroyDispmanxLayer(m_window); - eglDestroyContext(m_screen->display(), m_context); - } - - void createSurface() { - const QRect cr = cursorRect(); - m_window = createDispmanxLayer(cr.topLeft(), cr.size(), 50, DISPMANX_FLAGS_ALPHA_FROM_SOURCE); - m_surface = eglCreateWindowSurface(m_screen->display(), m_config, m_window, NULL); - } - - void createContext() { - eglBindAPI(EGL_OPENGL_ES_API); - QVector attrs; - attrs.append(EGL_CONTEXT_CLIENT_VERSION); - attrs.append(2); - attrs.append(EGL_NONE); - m_context = eglCreateContext(m_screen->display(), m_config, EGL_NO_CONTEXT, attrs.constData()); - } - - void drawInLayer() { - eglMakeCurrent(m_screen->display(), m_surface, m_surface, m_context); - - glClearColor(0, 0, 0, 0); - glClear(GL_COLOR_BUFFER_BIT); - draw(QRectF(QPointF(-1, 1), QPointF(1, -1))); - - eglSwapBuffers(m_screen->display(), m_surface); - eglMakeCurrent(m_screen->display(), EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - } - - void changeCursor(QCursor *cursor, QWindow *window) Q_DECL_OVERRIDE { - if (!setCurrentCursor(cursor)) - return; - - EGL_DISPMANX_WINDOW_T *eglWindow = static_cast(m_window); - if (QSize(eglWindow->width, eglWindow->height) != m_cursor.size) { - eglDestroySurface(m_screen->display(), m_surface); - destroyDispmanxLayer(m_window); - createSurface(); - } - drawInLayer(); - } - - void setPos(const QPoint &pos) Q_DECL_OVERRIDE { - m_cursor.pos = pos; - moveDispmanxLayer(m_window, cursorRect().topLeft()); - } - - void pointerEvent(const QMouseEvent &event) Q_DECL_OVERRIDE { - if (event.type() != QEvent::MouseMove) - return; - m_cursor.pos = event.pos(); - moveDispmanxLayer(m_window, cursorRect().topLeft()); - } - - void paintOnScreen() Q_DECL_OVERRIDE { } -private: - EGLConfig m_config; - EGLContext m_context; - EGLNativeWindowType m_window; - EGLSurface m_surface; -}; - class QEglFSPiHooks : public QEglFSHooks { public: @@ -230,9 +147,6 @@ public: virtual void destroyNativeWindow(EGLNativeWindowType window); virtual bool hasCapability(QPlatformIntegration::Capability cap) const; - QEglFSCursor *createCursor(QEglFSScreen *screen) const { - return new QEglFSPiCursor(screen); - } }; void QEglFSPiHooks::platformInit() -- cgit v1.2.3 From 24b440fb54c80c0b62aa7111734169d8709d392d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Tue, 10 Sep 2013 16:25:32 +0200 Subject: Static builds: Link QML plugins. Run qmlimportscanner, add found plugins to the LIBS line, generate qml_plugin_import.cpp. Change-Id: I6c6b927cceb36fa2dc405ad698f26d20398b33c8 Reviewed-by: Oswald Buddenhagen Reviewed-by: Richard Moe Gustavsen --- mkspecs/features/qt.prf | 86 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/mkspecs/features/qt.prf b/mkspecs/features/qt.prf index dc80f8d9e1..a4f082e056 100644 --- a/mkspecs/features/qt.prf +++ b/mkspecs/features/qt.prf @@ -73,6 +73,92 @@ wince*:static:gui { QTLIB += qmenu_wce.res } +# static builds: link qml import plugins into the app. +if(contains(QT, qml)|contains(QT_PRIVATE, qml)):contains(QT_CONFIG, static):contains(TEMPLATE, .*app):!host_build { + # run qmlimportscanner + qtPrepareTool(QMLIMPORTSCANNER, qmlimportscanner) + exists($$QMLIMPORTSCANNER) { + for (MODULE, QT_MODULES) { + PATH = $$eval(QT.$${MODULE}.qml) + !isEmpty(PATH): QMLPATHS += $$PATH + } + QMLPATHS = $$unique(QMLPATHS) + for (QMLPATH, QMLPATHS): \ + IMPORTPATHS += -importPath $$QMLPATH + + #message(run $$QMLIMPORTSCANNER $$_PRO_FILE_PWD_ $$IMPORTPATHS) + JSON = $$system($$QMLIMPORTSCANNER $$_PRO_FILE_PWD_ $$IMPORTPATHS) + } else { + error("qmlimportscanner is missing. Rebuild qtdeclarative/tools/qmlimportscanner.") + JSON = [] + } + + parseJson(JSON, IMPORTS)| error("Failed to parse qmlimportscanner output.") + + !isEmpty(IMPORTS._KEYS_) { + # add import plugins to LIBS line + for (key, IMPORTS._KEYS_): { + PATH = $$eval(IMPORTS.$${key}.path) + PLUGIN = $$eval(IMPORTS.$${key}.plugin) + !isEmpty(PATH):!isEmpty(PLUGIN): LIBS *= -L$$PATH -l$$PLUGIN + } + + # create qml_plugin_import.cpp + IMPORT_FILE_CONT = \ + "// This file is autogenerated by qmake. It imports static plugin classes for" \ + "// static plugins used by QML imports." \ + "$${LITERAL_HASH}include " + for (key, IMPORTS._KEYS_) { + PLUGIN = $$eval(IMPORTS.$${key}.plugin) + CLASSNAME = $$eval(IMPORTS.$${key}.classname) + !isEmpty(PLUGIN) { + !isEmpty(CLASSNAME) { + !contains(ADDED_IMPORTS, $$PLUGIN) { + ADDED_IMPORTS += $$PLUGIN + IMPORT_FILE_CONT += "Q_IMPORT_PLUGIN($$CLASSNAME)" + } + } else { + error("Plugin $$PLUGIN is missing a classname entry, please add one to the qmldir file.") + } + } + } + QML_IMPORT_CPP = $$OUT_PWD/$$lower($$basename(TARGET))_qml_plugin_import.cpp + write_file($$QML_IMPORT_CPP, IMPORT_FILE_CONT)|error("Aborting.") + SOURCES += $$QML_IMPORT_CPP + QMAKE_CLEAN += $$QML_IMPORT_CPP + + # copy qml files. this part is platform spesific. + macx { + # copy to Contents/Resources in the bundle. + QmlImports.path = Contents/Resources/ + QmlImports.files *= $$QMLPATHS + QMAKE_BUNDLE_DATA += QmlImports + + # place qt.conf in Contents/Resources in the app bundle + QT_CONF_CONTENTS = \ + "[Paths]" \ + "Imports = Resources/qml" \ + "Qml2Imports = Resources/qml" + QT_CONF = "$$OUT_PWD/$${TARGET}.app/Contents/Resources/qt.conf" + write_file($$QT_CONF, QT_CONF_CONTENTS)|error("Aborting.") + } else: ios { + # flat bundle layout (no Contents/Resources) + QmlImports.files *= $$QMLPATHS + QMAKE_BUNDLE_DATA += QmlImports + + # write qt.conf to OUT_PWD and make xcode copy it via QMAKE_BUNDLE_DATA + QT_CONF_CONTENTS = \ + "[Paths]" \ + "Imports = qml" \ + "Qml2Imports = qml" + QT_CONF = "$$OUT_PWD/qt.conf" + write_file($$QT_CONF, QT_CONF_CONTENTS)|error("Aborting.") + QtConf.files = $$QT_CONF + QMAKE_BUNDLE_DATA += QtConf + } + } +} + QT_PLUGIN_VERIFY = DEPLOYMENT_PLUGIN contains(QT_CONFIG, static) { QT_PLUGIN_VERIFY += QTPLUGIN -- cgit v1.2.3 From 0f47e8b8cdc64dd22baa08165def9f87b8fa3e12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 16 Oct 2013 18:56:49 +0200 Subject: iOS: Mark argument as unused for release builds Change-Id: I73497a6c16236f912646c9fbe9b136ff760ce4f7 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qioseventdispatcher.mm | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm index f7df792362..9991a59d9e 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.mm +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -496,6 +496,7 @@ void QIOSEventDispatcher::checkIfEventLoopShouldExit() void QIOSEventDispatcher::handleRunLoopExit(CFRunLoopActivity activity) { + Q_UNUSED(activity); Q_ASSERT(activity == kCFRunLoopExit); m_runLoopExitObserver.removeFromMode(kCFRunLoopCommonModes); -- cgit v1.2.3 From e6cac2c19315c9127f5b4048088e66da6b9296fe Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 16 Oct 2013 15:36:34 +0200 Subject: Refresh Windows printer list when QPrinterInfo.availablePrinters() is called. Introduce static query functions. Task-number: QTBUG-33666 Change-Id: I291098c9da82bc2cc24957044187e93cdc33c41d Reviewed-by: Oliver Wolff Reviewed-by: Joerg Bornemann --- .../windows/qwindowsprintersupport.cpp | 52 ++++++++++++++-------- .../printsupport/windows/qwindowsprintersupport.h | 4 ++ 2 files changed, 37 insertions(+), 19 deletions(-) diff --git a/src/plugins/printsupport/windows/qwindowsprintersupport.cpp b/src/plugins/printsupport/windows/qwindowsprintersupport.cpp index 36e7a3fb8e..2faebf6f64 100644 --- a/src/plugins/printsupport/windows/qwindowsprintersupport.cpp +++ b/src/plugins/printsupport/windows/qwindowsprintersupport.cpp @@ -42,6 +42,7 @@ #include "qwindowsprintersupport.h" #include +#include #include #include #include @@ -52,25 +53,7 @@ QT_BEGIN_NAMESPACE QWindowsPrinterSupport::QWindowsPrinterSupport() : QPlatformPrinterSupport() { - DWORD needed = 0; - DWORD returned = 0; - if (!EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL, 4, 0, 0, &needed, &returned)) { - LPBYTE buffer = new BYTE[needed]; - if (EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL, 4, buffer, needed, &needed, &returned)) { - PPRINTER_INFO_4 infoList = reinterpret_cast(buffer); - QString defaultPrinterName; - QString program; - QString port; - QWin32PrintEngine::queryDefaultPrinter(defaultPrinterName, program, port); - for (uint i = 0; i < returned; ++i) { - QString printerName(QString::fromWCharArray(infoList[i].pPrinterName)); - bool isDefault = (printerName == defaultPrinterName); - QPrinterInfo printerInfo = createPrinterInfo(printerName, QString(), QString(), QString(), isDefault, i); - m_printers.append(printerInfo); - } - } - delete [] buffer; - } + m_printers = QWindowsPrinterSupport::queryPrinters(); } QWindowsPrinterSupport::~QWindowsPrinterSupport() @@ -98,4 +81,35 @@ QList >QWindowsPrinterSupport::supportedSizesWithNames(co return QWin32PrintEngine::supportedSizesWithNames(printerInfo); } +QList QWindowsPrinterSupport::availablePrinters() +{ + m_printers = QWindowsPrinterSupport::queryPrinters(); + return QPlatformPrinterSupport::availablePrinters(); +} + +QList QWindowsPrinterSupport::queryPrinters() +{ + QList result; + DWORD needed = 0; + DWORD returned = 0; + if ((!EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL, 4, 0, 0, &needed, &returned) && GetLastError() != ERROR_INSUFFICIENT_BUFFER) + || !needed) { + return result; + } + QScopedArrayPointer buffer(new BYTE[needed]); + if (!EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL, 4, buffer.data(), needed, &needed, &returned)) + return result; + PPRINTER_INFO_4 infoList = reinterpret_cast(buffer.data()); + QString defaultPrinterName; + QString program; + QString port; + QWin32PrintEngine::queryDefaultPrinter(defaultPrinterName, program, port); + for (uint i = 0; i < returned; ++i) { + const QString printerName(QString::fromWCharArray(infoList[i].pPrinterName)); + const bool isDefault = (printerName == defaultPrinterName); + result.append(QPlatformPrinterSupport::createPrinterInfo(printerName, QString(), QString(), QString(), isDefault, i)); + } + return result; +} + QT_END_NAMESPACE diff --git a/src/plugins/printsupport/windows/qwindowsprintersupport.h b/src/plugins/printsupport/windows/qwindowsprintersupport.h index 1d5a4f3da4..1b1b1fa215 100644 --- a/src/plugins/printsupport/windows/qwindowsprintersupport.h +++ b/src/plugins/printsupport/windows/qwindowsprintersupport.h @@ -58,6 +58,10 @@ public: virtual QPaintEngine *createPaintEngine(QPrintEngine *printEngine, QPrinter::PrinterMode); virtual QList supportedPaperSizes(const QPrinterInfo &) const; virtual QList >supportedSizesWithNames(const QPrinterInfo &printerInfo) const; + virtual QList availablePrinters(); + +private: + static QList queryPrinters(); }; QT_END_NAMESPACE -- cgit v1.2.3 From b5fe1ed1724a34765a91faa135b2dd98e1941f58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 16 Oct 2013 17:40:01 +0200 Subject: qmake: Add support for QMAKE_{PRE,POST}_LINK in the Xcode generator Change-Id: I038cf0aebb74d7ecfe6cb3ed868287042342eb7e Reviewed-by: Richard Moe Gustavsen --- qmake/generators/mac/pbuilder_pbx.cpp | 39 +++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp index 03887e7938..524603aa63 100644 --- a/qmake/generators/mac/pbuilder_pbx.cpp +++ b/qmake/generators/mac/pbuilder_pbx.cpp @@ -1019,6 +1019,27 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) << "\t\t\t" << writeSettings("shellScript", "make -C " + IoUtils::shellQuoteUnix(qmake_getpwd()) + " -f " + IoUtils::shellQuoteUnix(mkfile)) << ";\n" << "\t\t};\n"; } + + if (!project->isEmpty("QMAKE_PRE_LINK")) { + QString phase_key = keyFor("QMAKE_PBX_PRELINK_BUILDPHASE"); + project->values("QMAKE_PBX_BUILDPHASES").append(phase_key); + t << "\t\t" << phase_key << " = {\n" + << "\t\t\t" << writeSettings("buildActionMask", "2147483647", SettingsNoQuote) << ";\n" + << "\t\t\t" << writeSettings("files", ProStringList(), SettingsAsList, 4) << ";\n" + // The build phases are not executed in the order they are defined, but by their + // resolved dependenices, so we have to ensure that this phase is run after the + // compilation phase, and before the link phase. Making the phase depend on all the + // object files, and "write" to the list of files to link achieves that. + << "\t\t\t" << writeSettings("inputPaths", ProStringList("$(OBJECT_FILE_DIR_$(CURRENT_VARIANT))/$(CURRENT_ARCH)/*" + Option::obj_ext), SettingsAsList, 4) << ";\n" + << "\t\t\t" << writeSettings("outputPaths", ProStringList("$(LINK_FILE_LIST_$(CURRENT_VARIANT)_$(CURRENT_ARCH))"), SettingsAsList, 4) << ";\n" + << "\t\t\t" << writeSettings("isa", "PBXShellScriptBuildPhase", SettingsNoQuote) << ";\n" + << "\t\t\t" << writeSettings("runOnlyForDeploymentPostprocessing", "0", SettingsNoQuote) << ";\n" + << "\t\t\t" << writeSettings("name", "Qt Prelink") << ";\n" + << "\t\t\t" << writeSettings("shellPath", "/bin/sh") << ";\n" + << "\t\t\t" << writeSettings("shellScript", project->values("QMAKE_PRE_LINK")) << ";\n" + << "\t\t};\n"; + } + //LIBRARY BUILDPHASE if(!project->isEmpty("QMAKE_PBX_LIBRARIES")) { tmp = project->values("QMAKE_PBX_LIBRARIES"); @@ -1044,6 +1065,24 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) << "\t\t\t" << writeSettings("name", escapeFilePath(grp)) << ";\n" << "\t\t};\n"; } + + if (!project->isEmpty("QMAKE_POST_LINK")) { + QString phase_key = keyFor("QMAKE_PBX_POSTLINK_BUILDPHASE"); + project->values("QMAKE_PBX_BUILDPHASES").append(phase_key); + t << "\t\t" << phase_key << " = {\n" + << "\t\t\t" << writeSettings("buildActionMask", "2147483647", SettingsNoQuote) << ";\n" + << "\t\t\t" << writeSettings("files", ProStringList(), SettingsAsList, 4) << ";\n" + // The build phases are not executed in the order they are defined, but by their + // resolved dependenices, so we have to ensure the phase is run after linking. + << "\t\t\t" << writeSettings("inputPaths", ProStringList("$(TARGET_BUILD_DIR)/$(EXECUTABLE_PATH)"), SettingsAsList, 4) << ";\n" + << "\t\t\t" << writeSettings("isa", "PBXShellScriptBuildPhase", SettingsNoQuote) << ";\n" + << "\t\t\t" << writeSettings("runOnlyForDeploymentPostprocessing", "0", SettingsNoQuote) << ";\n" + << "\t\t\t" << writeSettings("name", "Qt Postlink") << ";\n" + << "\t\t\t" << writeSettings("shellPath", "/bin/sh") << ";\n" + << "\t\t\t" << writeSettings("shellScript", project->values("QMAKE_POST_LINK")) << ";\n" + << "\t\t};\n"; + } + if (!project->isEmpty("DESTDIR")) { QString phase_key = keyFor("QMAKE_PBX_TARGET_COPY_PHASE"); QString destDir = project->first("DESTDIR").toQString(); -- cgit v1.2.3 From 32f34ddbe1a57255194703955730058386789cf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 16 Oct 2013 19:06:47 +0200 Subject: iOS: Wrap user's main by renaming symbol and relying on weak linking This approach is similar to the earlier apprach of defining main=qt_main when building the user's sources, but uses the linker to rename the symbol instead, which is less fragile than using the preprocessor. To keep the hybrid usecase unaffected by our wrapper logic we declare both our main wrapper and a fallback qt_main as weak symbols, which ensures that when the user's application links in our plugin the real main/qt_main provided by the user is preferred over our weak symbols. Change-Id: Ic76f3ba8932430c4b13a1d3a40b8ed2322fe5eea Reviewed-by: Simon Hausmann --- mkspecs/macx-ios-clang/features/qt.prf | 76 ++++++++---------------- src/plugins/platforms/ios/qioseventdispatcher.mm | 17 +++++- 2 files changed, 39 insertions(+), 54 deletions(-) diff --git a/mkspecs/macx-ios-clang/features/qt.prf b/mkspecs/macx-ios-clang/features/qt.prf index 9fa882c99f..2897c62819 100644 --- a/mkspecs/macx-ios-clang/features/qt.prf +++ b/mkspecs/macx-ios-clang/features/qt.prf @@ -1,8 +1,5 @@ equals(TEMPLATE, app):contains(QT, gui(-private)?) { - !macx-xcode: \ - error("Linking the iOS platform plugin requires bulding through Xcode") - LIBS *= -L$$[QT_INSTALL_PLUGINS/get]/platforms lib_name = qios @@ -21,54 +18,31 @@ equals(TEMPLATE, app):contains(QT, gui(-private)?) { CONFIG -= import_qpa_plugin !no_main_wrapper { - # Instead of messing with the user's main function we go the other - # way and change the application entry point to call our main wrapper. - # This entry point is the 'start' symbol, provided by crt1.o, so we - # make a copy of the file and rename the '_main' unresolved symbol - # to our wrapper function, '_qtmn', injecting ourselves into the app - # startup. Once Apple starts shipping the LLVM linker (lld) we may - # get rid of this step completely and just pass -e _qtmn to the - # linker, taking advantage of the new LC_MAIN load command. - - # We know that iOS 3.1 and up uses crt1.3.1.o (technically not - # true for simulator, but the SDK has a symlink to the correct file). - original_crt_path = "$(SDK_DIR)/usr/lib/crt1.3.1.o" - - xcode_objects_path = "$(OBJECT_FILE_DIR_$(CURRENT_VARIANT))/$(CURRENT_ARCH)" - custom_crt_filename = "crt1_qt.o" - custom_crt_path = "$$xcode_objects_path/$$custom_crt_filename" - - EOC = $$escape_expand(\\n\\t) - create_custom_crt.commands = \ - # Copy original crt1 to build directory - "$$QMAKE_COPY_FILE $$original_crt_path $$custom_crt_path $$EOC" \ - # And rename all occurrences of _main to _qtmn - "strings -t d - $${custom_crt_path}" \ - "| sed -n 's/^\\([0-9]\\{1,\\}\\) _main\$\$/\1/p'" \ - "| while read offset; do" \ - "printf '_qtmn'" \ - "| dd of=$${custom_crt_path} bs=1 seek=\$\$offset conv=notrunc >/dev/null 2>&1" \ - "; done" - create_custom_crt.depends = $$original_crt_path - create_custom_crt.target = $$custom_crt_path - preprocess.depends = create_custom_crt - QMAKE_EXTRA_TARGETS += create_custom_crt preprocess - - clean_custom_crt.commands = "$$QMAKE_DEL_FILE $$custom_crt_path" - preprocess_clean.depends += clean_custom_crt - QMAKE_EXTRA_TARGETS += clean_custom_crt preprocess_clean - - # Prevent usage of new LC_MAIN load command, which skips start/crt1 - # and calls main from the loader. We rely on injecting into start. - QMAKE_LFLAGS += -Wl,-no_new_main - - # Explicitly link against our modified crt1 object - QMAKE_LFLAGS += -nostartfiles -l$${custom_crt_filename} - - # Workaround for QMAKE_PBX_LIBPATHS mangling the Xcode variables - lib_search_path.name = LIBRARY_SEARCH_PATHS - lib_search_path.value = $$xcode_objects_path - QMAKE_MAC_XCODE_SETTINGS += lib_search_path + # We use ld to rename the _main symbol to _qt_main, so that we don't get a symbol clash + # with the _main we provide that calls UIApplicationMain. We need to make a copy of the + # original object file, as ld will not copy over DWARF debug information to the output + # file. Instead, it will inject a reference back to the original object file, so when + # Xcode runs dsymutil to make the final dSYM file it will still find the debug info + # for the object file that provided the original _main. This back-reference has the + # interesting side-effect of the debug information still referring to the original + # symbol name, so stack-traces will show both our wrapper main and the original + # user main as 'main', and adding a symbolic breakpoint for 'main' will break on + # both functions. Although a bit weird, it's a good thing, as the user will still be + # able to add symbolic breakpoints for 'main', not caring that the symbol is actually + # called 'qt_main' now. + + isEmpty(OBJECTS_DIR): \ + OBJECTS_DIR = . + + !isEmpty(QMAKE_PRE_LINK): \ + QMAKE_PRE_LINK += ";" + + QMAKE_PRE_LINK += \ + "for f in $(find $${OBJECTS_DIR} -name '*.o'); do" \ + "(nm $f | grep -q 'T _main' && cp $f $f.original" \ + "&& ld -r -alias _main _qt_main -unexported_symbol _main $f.original -o $f)" \ + "|| true" \ + "; done" } } diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm index 9991a59d9e..3dd9c7ad9f 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.mm +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -213,7 +213,7 @@ static int infoPlistValue(NSString* key, int defaultValue) return value ? [value intValue] : defaultValue; } -extern "C" int qtmn(int argc, char *argv[]) +extern "C" int __attribute__((weak)) main(int argc, char *argv[]) { @autoreleasepool { size_t defaultStackSize = 512 * kBytesPerKiloByte; // Same as secondary threads @@ -248,7 +248,18 @@ enum SetJumpResult kJumpedFromUserMainTrampoline, }; -extern "C" int main(int argc, char *argv[]); +// We define qt_main so that user_main_trampoline() will not cause +// missing symbols in the case of hybrid applications that don't +// user our main wrapper. Since the symbol is weak, it will not +// get used or cause a clash in the normal Qt application usecase, +// where we rename main to qt_main. +extern "C" int __attribute__((weak)) qt_main(int argc, char *argv[]) +{ + Q_UNUSED(argc); + Q_UNUSED(argv); + + Q_UNREACHABLE(); +} static void __attribute__((noinline, noreturn)) user_main_trampoline() { @@ -261,7 +272,7 @@ static void __attribute__((noinline, noreturn)) user_main_trampoline() strcpy(argv[i], [arg cStringUsingEncoding:[NSString defaultCStringEncoding]]); } - int exitCode = main(argc, argv); + int exitCode = qt_main(argc, argv); delete[] argv; qEventDispatcherDebug() << "Returned from main with exit code " << exitCode; -- cgit v1.2.3 From 27316e097f95625aba19803ad8a47c4c0fece8fc Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 17 Oct 2013 13:01:15 +0300 Subject: Clear QGuiApplicationPrivate::tabletPressTarget in ~QWindow. Task-number: QTBUG-34007 Change-Id: I81b8496746f425f58a21b18ffaf96dfdbbe2a815 Reviewed-by: Laszlo Agocs --- src/gui/kernel/qwindow.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index f2e60e0ff3..13218fa178 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -227,6 +227,8 @@ QWindow::~QWindow() QGuiApplicationPrivate::focus_window = 0; if (QGuiApplicationPrivate::currentMouseWindow == this) QGuiApplicationPrivate::currentMouseWindow = 0; + if (QGuiApplicationPrivate::tabletPressTarget == this) + QGuiApplicationPrivate::tabletPressTarget = 0; QGuiApplicationPrivate::window_list.removeAll(this); destroy(); } -- cgit v1.2.3 From 73e3d2f6cb002be4ce409c3738db74b61beb12f4 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 17 Oct 2013 11:13:01 +0200 Subject: Windows: Capture last error right after CreateDirectory() in QFileSystemEngine. Custom allocators invoked by freeing the QString contents might change it. Task-number: QTBUG-34046 Task-number: QTBUG-32314 Change-Id: Ied5305c21fcce228448fe565899163997536ea7a Reviewed-by: Joerg Bornemann --- src/corelib/io/qfilesystemengine_win.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index 57231b57a9..257f18a6bb 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -965,8 +965,10 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM return data.hasFlags(what); } -static inline bool mkDir(const QString &path) +static inline bool mkDir(const QString &path, DWORD *lastError = 0) { + if (lastError) + *lastError = 0; #if defined(Q_OS_WINCE) // Unfortunately CreateDirectory returns true for paths longer than // 256, but does not create a directory. It starts to fail, when @@ -986,7 +988,11 @@ static inline bool mkDir(const QString &path) if (platformId == 1 && QFSFileEnginePrivate::longFileName(path).size() > 256) return false; #endif - return ::CreateDirectory((wchar_t*)QFSFileEnginePrivate::longFileName(path).utf16(), 0); + const QString longPath = QFSFileEnginePrivate::longFileName(path); + const bool result = ::CreateDirectory((wchar_t*)longPath.utf16(), 0); + if (lastError) // Capture lastError before any QString is freed since custom allocators might change it. + *lastError = GetLastError(); + return result; } static inline bool rmDir(const QString &path) @@ -1051,9 +1057,9 @@ bool QFileSystemEngine::createDirectory(const QFileSystemEntry &entry, bool crea slash = dirName.length(); } if (slash) { + DWORD lastError; QString chunk = dirName.left(slash); - if (!mkDir(chunk)) { - const DWORD lastError = GetLastError(); + if (!mkDir(chunk, &lastError)) { if (lastError == ERROR_ALREADY_EXISTS || lastError == ERROR_ACCESS_DENIED) { bool existed = false; if (isDirPath(chunk, &existed) && existed) -- cgit v1.2.3 From fbfc8ffbf39e2e7a540d4d576ec61bea7db63416 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Wed, 2 Oct 2013 08:52:26 +0200 Subject: Implement native gestures on OS X. Add QWindowSystemInterface::GestureEvent and QNativeGestureEvent to QtGui. These events are copies of Qt4's QNativeGestureEvent, where it was an implementation detail of QGestureManager. Add gesture message handlers to QNSView and bring back the Mac gesture recognizers for QGestureManager. Task-number: QTBUG-28126 Change-Id: I1304e09e776fa7c44d133d54ca8b895ca2f544c5 Reviewed-by: Friedemann Kleint Reviewed-by: Gunnar Sletta --- src/corelib/global/qnamespace.h | 12 ++ src/corelib/kernel/qcoreevent.h | 2 +- src/gui/kernel/qevent.cpp | 115 +++++++++++ src/gui/kernel/qevent.h | 28 +++ src/gui/kernel/qguiapplication.cpp | 13 ++ src/gui/kernel/qguiapplication_p.h | 1 + src/gui/kernel/qwindowsysteminterface.cpp | 29 +++ src/gui/kernel/qwindowsysteminterface.h | 9 + src/gui/kernel/qwindowsysteminterface_p.h | 16 ++ src/plugins/platforms/cocoa/qnsview.mm | 96 ++++++++++ src/widgets/kernel/kernel.pri | 56 +----- src/widgets/kernel/qgesture_p.h | 35 ---- src/widgets/kernel/qgesturemanager.cpp | 6 +- src/widgets/kernel/qmacgesturerecognizer.cpp | 275 +++++++++++++++++++++++++++ src/widgets/kernel/qmacgesturerecognizer_p.h | 102 ++++++++++ src/widgets/kernel/qwidgetwindow.cpp | 27 +++ src/widgets/kernel/qwidgetwindow_qpa_p.h | 3 + 17 files changed, 733 insertions(+), 92 deletions(-) create mode 100644 src/widgets/kernel/qmacgesturerecognizer.cpp create mode 100644 src/widgets/kernel/qmacgesturerecognizer_p.h diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index e2c6039989..8a46f3a6ab 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -1557,6 +1557,18 @@ public: IgnoredGesturesPropagateToParent = 0x04 }; Q_DECLARE_FLAGS(GestureFlags, GestureFlag) + + enum NativeGestureType + { + BeginNativeGesture, + EndNativeGesture, + PanNativeGesture, + ZoomNativeGesture, + SmartZoomNativeGesture, + RotateNativeGesture, + SwipeNativeGesture + }; + #endif // QT_NO_GESTURES enum NavigationMode diff --git a/src/corelib/kernel/qcoreevent.h b/src/corelib/kernel/qcoreevent.h index 2ca0a7d0b0..e974c4d226 100644 --- a/src/corelib/kernel/qcoreevent.h +++ b/src/corelib/kernel/qcoreevent.h @@ -249,7 +249,7 @@ public: TouchEnd = 196, #ifndef QT_NO_GESTURES - NativeGesture = 197, // Internal for platform gesture support + NativeGesture = 197, // QtGui native gesture #endif RequestSoftwareInputPanel = 199, CloseSoftwareInputPanel = 200, diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index ef9a3a1225..06fa1f3550 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -2263,6 +2263,121 @@ QTabletEvent::~QTabletEvent() #endif // QT_NO_TABLETEVENT +/*! + \class QNativeGestureEvent + \since 5.2 + \brief The QNativeGestureEvent class contains parameters that describe a gesture event. + \inmodule QtGui + \ingroup events + + Native gesture events are generated by the operating system, typically by + interpreting touch events. Gesture events are high-level events such + as zoom or rotate. + + \table + \header + \li Event Type + \li Description + \li Touch equence + \row + \li Qt::ZoomNativeGesture + \li Magnification delta in percent. + \li OS X: Two-finger pinch. + \row + \li Qt::SmartZoomNativeGesture + \li Boolean magnification state. + \li OS X: Two-finger douple tap (trackpad) / One-finger douple tap (magic mouse). + \row + \li Qt::RotateNativeGesture + \li Rotation delta in degrees. + \li OS X: Two-finger rotate. + \endtable + + + In addition, BeginNativeGesture and EndNativeGesture are sent before and after + gesture event streams: + + BeginNativeGesture + ZoomNativeGesture + ZoomNativeGesture + ZoomNativeGesture + EndNativeGesture + + \sa Qt::NativeGestureType, QGestureEvent +*/ + +/*! + Constructs a native gesture event of type \a type. + + The points \a localPos, \a windowPos and \a screenPos specify the + gesture position relative to the receiving widget or item, + window, and screen, respectively. + + \a realValue is the OS X event parameter, \a sequenceId and \a intValue are the Windows event parameters. +*/ +QNativeGestureEvent::QNativeGestureEvent(Qt::NativeGestureType type, const QPointF &localPos, const QPointF &windowPos, + const QPointF &screenPos, qreal realValue, ulong sequenceId, quint64 intValue) + : QInputEvent(QEvent::NativeGesture), mGestureType(type), + mLocalPos(localPos), mWindowPos(windowPos), mScreenPos(screenPos), mRealValue(realValue), + mSequenceId(sequenceId), mIntValue(intValue) +{ } + +/*! + \fn QNativeGestureEvent::gestureType() const + \since 5.2 + + Returns the gesture type. +*/ + +/*! + \fn QNativeGestureEvent::value() const + \since 5.2 + + Returns the gesture value. The value should be interpreted based on the + gesture type. For example, a Zoom gesture provides a scale factor while a Rotate + gesture provides a rotation delta. + + \sa QNativeGestureEvent, gestureType() +*/ + +/*! + \fn QPoint QNativeGestureEvent::globalPos() const + \since 5.2 + + Returns the position of the gesture as a QPointF in screen coordinates +*/ + +/*! + \fn QPoint QNativeGestureEvent::pos() const + \since 5.2 + + Returns the position of the mouse cursor, relative to the widget + or item that received the event. +*/ + +/*! + \fn QPointF QNativeGestureEvent::localPos() const + \since 5.2 + + Returns the position of the gesture as a QPointF, relative to the + widget or item that received the event. +*/ + +/*! + \fn QPointF QNativeGestureEvent::screenPos() const + \since 5.2 + + Returns the position of the gesture as a QPointF in screen coordinates. +*/ + +/*! + \fn QPointF QNativeGestureEvent::windowPos() const + \since 5.2 + + Returns the position of the gesture as a QPointF, relative to the + window that received the event. +*/ + #ifndef QT_NO_DRAGANDDROP /*! Creates a QDragMoveEvent of the required \a type indicating diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h index 0c1cf70420..d22e423248 100644 --- a/src/gui/kernel/qevent.h +++ b/src/gui/kernel/qevent.h @@ -268,6 +268,34 @@ protected: }; #endif // QT_NO_TABLETEVENT +#ifndef QT_NO_GESTURES +class Q_GUI_EXPORT QNativeGestureEvent : public QInputEvent +{ +public: + QNativeGestureEvent(Qt::NativeGestureType type, const QPointF &localPos, const QPointF &windowPos, + const QPointF &screenPos, qreal value, ulong sequenceId, quint64 intArgument); + Qt::NativeGestureType gestureType() const { return mGestureType; } + qreal value() const { return mRealValue; } + +#ifndef QT_NO_INTEGER_EVENT_COORDINATES + inline const QPoint pos() const { return mLocalPos.toPoint(); } + inline const QPoint globalPos() const { return mScreenPos.toPoint(); } +#endif + const QPointF &localPos() const { return mLocalPos; } + const QPointF &windowPos() const { return mWindowPos; } + const QPointF &screenPos() const { return mScreenPos; } + +protected: + Qt::NativeGestureType mGestureType; + QPointF mLocalPos; + QPointF mWindowPos; + QPointF mScreenPos; + qreal mRealValue; + ulong mSequenceId; + quint64 mIntValue; +}; +#endif // QT_NO_GESTURES + class Q_GUI_EXPORT QKeyEvent : public QInputEvent { public: diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 1e3ea3092f..d254f7c9bc 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -1473,6 +1473,10 @@ void QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePriv QGuiApplicationPrivate::processTabletLeaveProximityEvent( static_cast(e)); break; + case QWindowSystemInterfacePrivate::Gesture: + QGuiApplicationPrivate::processGestureEvent( + static_cast(e)); + break; case QWindowSystemInterfacePrivate::PlatformPanel: QGuiApplicationPrivate::processPlatformPanelEvent( static_cast(e)); @@ -1958,6 +1962,15 @@ void QGuiApplicationPrivate::processTabletLeaveProximityEvent(QWindowSystemInter #endif } +#ifndef QT_NO_GESTURES +void QGuiApplicationPrivate::processGestureEvent(QWindowSystemInterfacePrivate::GestureEvent *e) +{ + QNativeGestureEvent ev(e->type, e->pos, e->pos, e->globalPos, e->realValue, e->sequenceId, e->intValue); + ev.setTimestamp(e->timestamp); + QGuiApplication::sendSpontaneousEvent(e->window, &ev); +} +#endif // QT_NO_GESTURES + void QGuiApplicationPrivate::processPlatformPanelEvent(QWindowSystemInterfacePrivate::PlatformPanelEvent *e) { if (!e->window) diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h index d1716a6e28..65c6d814e6 100644 --- a/src/gui/kernel/qguiapplication_p.h +++ b/src/gui/kernel/qguiapplication_p.h @@ -148,6 +148,7 @@ public: static void processTabletEvent(QWindowSystemInterfacePrivate::TabletEvent *e); static void processTabletEnterProximityEvent(QWindowSystemInterfacePrivate::TabletEnterProximityEvent *e); static void processTabletLeaveProximityEvent(QWindowSystemInterfacePrivate::TabletLeaveProximityEvent *e); + static void processGestureEvent(QWindowSystemInterfacePrivate::GestureEvent *e); static void processPlatformPanelEvent(QWindowSystemInterfacePrivate::PlatformPanelEvent *e); #ifndef QT_NO_CONTEXTMENU diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp index d62330083e..902c32419d 100644 --- a/src/gui/kernel/qwindowsysteminterface.cpp +++ b/src/gui/kernel/qwindowsysteminterface.cpp @@ -669,6 +669,35 @@ void QWindowSystemInterface::handleTabletLeaveProximityEvent(int device, int poi handleTabletLeaveProximityEvent(time, device, pointerType, uid); } +#ifndef QT_NO_GESTURES +void QWindowSystemInterface::handleGestureEvent(QWindow *window, ulong timestamp, Qt::NativeGestureType type, + QPointF &local, QPointF &global) +{ + QWindowSystemInterfacePrivate::GestureEvent *e = + new QWindowSystemInterfacePrivate::GestureEvent(window, timestamp, type, local, global); + QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); +} + +void QWindowSystemInterface::handleGestureEventWithRealValue(QWindow *window, ulong timestamp, Qt::NativeGestureType type, + qreal value, QPointF &local, QPointF &global) +{ + QWindowSystemInterfacePrivate::GestureEvent *e = + new QWindowSystemInterfacePrivate::GestureEvent(window, timestamp, type, local, global); + e->realValue = value; + QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); +} + +void QWindowSystemInterface::handleGestureEventWithSequenceIdAndValue(QWindow *window, ulong timestamp, Qt::NativeGestureType type, + ulong sequenceId, quint64 value, QPointF &local, QPointF &global) +{ + QWindowSystemInterfacePrivate::GestureEvent *e = + new QWindowSystemInterfacePrivate::GestureEvent(window, timestamp, type, local, global); + e->sequenceId = sequenceId; + e->intValue = value; + QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); +} +#endif // QT_NO_GESTURES + void QWindowSystemInterface::handlePlatformPanelEvent(QWindow *w) { QWindowSystemInterfacePrivate::PlatformPanelEvent *e = diff --git a/src/gui/kernel/qwindowsysteminterface.h b/src/gui/kernel/qwindowsysteminterface.h index c8e464f985..d8d0922b96 100644 --- a/src/gui/kernel/qwindowsysteminterface.h +++ b/src/gui/kernel/qwindowsysteminterface.h @@ -177,6 +177,15 @@ public: static void handleTabletLeaveProximityEvent(ulong timestamp, int device, int pointerType, qint64 uid); static void handleTabletLeaveProximityEvent(int device, int pointerType, qint64 uid); +#ifndef QT_NO_GESTURES + static void handleGestureEvent(QWindow *window, ulong timestamp, Qt::NativeGestureType type, + QPointF &local, QPointF &global); + static void handleGestureEventWithRealValue(QWindow *window, ulong timestamp, Qt::NativeGestureType type, + qreal value, QPointF &local, QPointF &global); + static void handleGestureEventWithSequenceIdAndValue(QWindow *window, ulong timestamp,Qt::NativeGestureType type, + ulong sequenceId, quint64 value, QPointF &local, QPointF &global); +#endif // QT_NO_GESTURES + static void handlePlatformPanelEvent(QWindow *w); #ifndef QT_NO_CONTEXTMENU static void handleContextMenuEvent(QWindow *w, bool mouseTriggered, diff --git a/src/gui/kernel/qwindowsysteminterface_p.h b/src/gui/kernel/qwindowsysteminterface_p.h index 46479701cc..03e2d420f0 100644 --- a/src/gui/kernel/qwindowsysteminterface_p.h +++ b/src/gui/kernel/qwindowsysteminterface_p.h @@ -91,6 +91,7 @@ public: PlatformPanel = UserInputEvent | 0x17, ContextMenu = UserInputEvent | 0x18, EnterWhatsThisMode = UserInputEvent | 0x19, + Gesture = UserInputEvent | 0x1a, ApplicationStateChanged = 0x19, FlushEvents = 0x20, WindowScreenChanged = 0x21 @@ -398,6 +399,21 @@ public: }; #endif + class GestureEvent : public InputEvent { + public: + GestureEvent(QWindow *window, ulong time, Qt::NativeGestureType type, QPointF pos, QPointF globalPos) + : InputEvent(window, time, Gesture, Qt::NoModifier), type(type), pos(pos), globalPos(globalPos), + realValue(0), sequenceId(0), intValue(0) { } + Qt::NativeGestureType type; + QPointF pos; + QPointF globalPos; + // Mac + qreal realValue; + // Windows + ulong sequenceId; + quint64 intValue; + }; + class WindowSystemEventList { QList impl; mutable QMutex mutex; diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index f471a61aa0..f90fc6b205 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -975,6 +975,102 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent) QWindowSystemInterface::handleTouchEvent(m_window, timestamp * 1000, touchDevice, points); } +#ifndef QT_NO_GESTURES +//#define QT_COCOA_ENABLE_GESTURE_DEBUG +- (void)magnifyWithEvent:(NSEvent *)event +{ +#ifdef QT_COCOA_ENABLE_GESTURE_DEBUG + qDebug() << "magnifyWithEvent" << [event magnification]; +#endif + const NSTimeInterval timestamp = [event timestamp]; + QPointF windowPoint; + QPointF screenPoint; + [self convertFromEvent:event toWindowPoint:&windowPoint andScreenPoint:&screenPoint]; + QWindowSystemInterface::handleGestureEventWithRealValue(m_window, timestamp, Qt::ZoomNativeGesture, + [event magnification], windowPoint, screenPoint); +} + +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8 +- (void)smartMagnifyWithEvent:(NSEvent *)event +{ + static bool zoomIn = true; +#ifdef QT_COCOA_ENABLE_GESTURE_DEBUG + qDebug() << "smartMagnifyWithEvent" << zoomIn; +#endif + const NSTimeInterval timestamp = [event timestamp]; + QPointF windowPoint; + QPointF screenPoint; + [self convertFromEvent:event toWindowPoint:&windowPoint andScreenPoint:&screenPoint]; + QWindowSystemInterface::handleGestureEventWithRealValue(m_window, timestamp, Qt::SmartZoomNativeGesture, + zoomIn ? 1.0f : 0.0f, windowPoint, screenPoint); + zoomIn = !zoomIn; +} +#endif + +- (void)rotateWithEvent:(NSEvent *)event +{ +#ifdef QT_COCOA_ENABLE_GESTURE_DEBUG + qDebug() << "rotateWithEvent" << [event rotation]; +#endif + const NSTimeInterval timestamp = [event timestamp]; + QPointF windowPoint; + QPointF screenPoint; + [self convertFromEvent:event toWindowPoint:&windowPoint andScreenPoint:&screenPoint]; + QWindowSystemInterface::handleGestureEventWithRealValue(m_window, timestamp, Qt::RotateNativeGesture, + -[event rotation], windowPoint, screenPoint); +} + +- (void)swipeWithEvent:(NSEvent *)event +{ +#ifdef QT_COCOA_ENABLE_GESTURE_DEBUG + qDebug() << "swipeWithEvent" << [event deltaX] << [event deltaY]; +#endif + const NSTimeInterval timestamp = [event timestamp]; + QPointF windowPoint; + QPointF screenPoint; + [self convertFromEvent:event toWindowPoint:&windowPoint andScreenPoint:&screenPoint]; + + qreal angle = 0.0f; + if ([event deltaX] == 1) + angle = 180.0f; + else if ([event deltaX] == -1) + angle = 0.0f; + else if ([event deltaY] == 1) + angle = 90.0f; + else if ([event deltaY] == -1) + angle = 270.0f; + + QWindowSystemInterface::handleGestureEventWithRealValue(m_window, timestamp, Qt::SwipeNativeGesture, + angle, windowPoint, screenPoint); +} + +- (void)beginGestureWithEvent:(NSEvent *)event +{ +#ifdef QT_COCOA_ENABLE_GESTURE_DEBUG + qDebug() << "beginGestureWithEvent"; +#endif + const NSTimeInterval timestamp = [event timestamp]; + QPointF windowPoint; + QPointF screenPoint; + [self convertFromEvent:event toWindowPoint:&windowPoint andScreenPoint:&screenPoint]; + QWindowSystemInterface::handleGestureEvent(m_window, timestamp, Qt::BeginNativeGesture, + windowPoint, screenPoint); +} + +- (void)endGestureWithEvent:(NSEvent *)event +{ +#ifdef QT_COCOA_ENABLE_GESTURE_DEBUG + qDebug() << "endGestureWithEvent"; +#endif + const NSTimeInterval timestamp = [event timestamp]; + QPointF windowPoint; + QPointF screenPoint; + [self convertFromEvent:event toWindowPoint:&windowPoint andScreenPoint:&screenPoint]; + QWindowSystemInterface::handleGestureEvent(m_window, timestamp, Qt::EndNativeGesture, + windowPoint, screenPoint); +} +#endif // QT_NO_GESTURES + #ifndef QT_NO_WHEELEVENT - (void)scrollWheel:(NSEvent *)theEvent { diff --git a/src/widgets/kernel/kernel.pri b/src/widgets/kernel/kernel.pri index 533b696faa..444b9b687f 100644 --- a/src/widgets/kernel/kernel.pri +++ b/src/widgets/kernel/kernel.pri @@ -66,59 +66,9 @@ SOURCES += \ kernel/qwidgetwindow.cpp \ kernel/qwindowcontainer.cpp - -# TODO -false:!x11:mac { - SOURCES += \ - kernel/qclipboard_mac.cpp \ - kernel/qmime_mac.cpp \ - kernel/qt_mac.cpp \ - kernel/qkeymapper_mac.cpp - - OBJECTIVE_HEADERS += \ - qcocoawindow_mac_p.h \ - qcocoapanel_mac_p.h \ - qcocoawindowdelegate_mac_p.h \ - qcocoaview_mac_p.h \ - qcocoaapplication_mac_p.h \ - qcocoaapplicationdelegate_mac_p.h \ - qmacgesturerecognizer_mac_p.h \ - qmultitouch_mac_p.h \ - qcocoasharedwindowmethods_mac_p.h \ - qcocoaintrospection_p.h - - OBJECTIVE_SOURCES += \ - kernel/qcursor_mac.mm \ - kernel/qdnd_mac.mm \ - kernel/qapplication_mac.mm \ - kernel/qwidget_mac.mm \ - kernel/qcocoapanel_mac.mm \ - kernel/qcocoaview_mac.mm \ - kernel/qcocoawindow_mac.mm \ - kernel/qcocoawindowdelegate_mac.mm \ - kernel/qcocoaapplication_mac.mm \ - kernel/qcocoaapplicationdelegate_mac.mm \ - kernel/qt_cocoa_helpers_mac.mm \ - kernel/qdesktopwidget_mac.mm \ - kernel/qeventdispatcher_mac.mm \ - kernel/qcocoawindowcustomthemeframe_mac.mm \ - kernel/qmacgesturerecognizer_mac.mm \ - kernel/qmultitouch_mac.mm \ - kernel/qcocoaintrospection_mac.mm - - HEADERS += \ - kernel/qt_cocoa_helpers_mac_p.h \ - kernel/qcocoaapplication_mac_p.h \ - kernel/qcocoaapplicationdelegate_mac_p.h \ - kernel/qeventdispatcher_mac_p.h - - MENU_NIB.files = mac/qt_menu.nib - MENU_NIB.path = Resources - MENU_NIB.version = Versions - QMAKE_BUNDLE_DATA += MENU_NIB - RESOURCES += mac/macresources.qrc - - LIBS_PRIVATE += -framework AppKit +macx: { + HEADERS += kernel/qmacgesturerecognizer_p.h + SOURCES += kernel/qmacgesturerecognizer.cpp } wince*: { diff --git a/src/widgets/kernel/qgesture_p.h b/src/widgets/kernel/qgesture_p.h index c041af7317..ae203d2819 100644 --- a/src/widgets/kernel/qgesture_p.h +++ b/src/widgets/kernel/qgesture_p.h @@ -190,41 +190,6 @@ public: static int Timeout; }; -#ifndef QT_NO_GESTURES -class QNativeGestureEvent : public QEvent -{ -public: - enum Type { - None, - GestureBegin, - GestureEnd, - Pan, - Zoom, - Rotate, - Swipe - }; - - QNativeGestureEvent() - : QEvent(QEvent::NativeGesture), gestureType(None), percentage(0) -#ifdef Q_WS_WIN - , sequenceId(0), argument(0) -#endif - { - } - - Type gestureType; - float percentage; - QPoint position; - float angle; -#ifdef Q_WS_WIN - ulong sequenceId; - quint64 argument; -#endif -}; - -#endif // QT_NO_GESTURES - - QT_END_NAMESPACE #endif // QT_NO_GESTURES diff --git a/src/widgets/kernel/qgesturemanager.cpp b/src/widgets/kernel/qgesturemanager.cpp index d90b187bf0..6a0ccacdaa 100644 --- a/src/widgets/kernel/qgesturemanager.cpp +++ b/src/widgets/kernel/qgesturemanager.cpp @@ -51,8 +51,8 @@ #include "qevent.h" #include "qgraphicsitem.h" -#ifdef Q_WS_MAC -#include "qmacgesturerecognizer_mac_p.h" +#ifdef Q_OS_MAC +#include "qmacgesturerecognizer_p.h" #endif #if defined(Q_WS_WIN) && !defined(QT_NO_NATIVE_GESTURES) #include "qwinnativepangesturerecognizer_win_p.h" @@ -76,7 +76,7 @@ QGestureManager::QGestureManager(QObject *parent) { qRegisterMetaType(); -#if defined(Q_WS_MAC) +#if defined(Q_OS_MAC) registerGestureRecognizer(new QMacSwipeGestureRecognizer); registerGestureRecognizer(new QMacPinchGestureRecognizer); registerGestureRecognizer(new QMacPanGestureRecognizer); diff --git a/src/widgets/kernel/qmacgesturerecognizer.cpp b/src/widgets/kernel/qmacgesturerecognizer.cpp new file mode 100644 index 0000000000..feb779e53f --- /dev/null +++ b/src/widgets/kernel/qmacgesturerecognizer.cpp @@ -0,0 +1,275 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtWidgets module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qmacgesturerecognizer_p.h" +#include "qgesture.h" +#include "qgesture_p.h" +#include "qevent.h" +#include "qwidget.h" +#include "qdebug.h" + +#ifndef QT_NO_GESTURES + +QT_BEGIN_NAMESPACE + +QMacSwipeGestureRecognizer::QMacSwipeGestureRecognizer() +{ +} + +QGesture *QMacSwipeGestureRecognizer::create(QObject * /*target*/) +{ + return new QSwipeGesture; +} + +QGestureRecognizer::Result +QMacSwipeGestureRecognizer::recognize(QGesture *gesture, QObject *obj, QEvent *event) +{ + if (event->type() == QEvent::NativeGesture && obj->isWidgetType()) { + QNativeGestureEvent *ev = static_cast(event); + switch (ev->gestureType()) { + case Qt::SwipeNativeGesture: { + QSwipeGesture *g = static_cast(gesture); + g->setSwipeAngle(ev->value()); + g->setHotSpot(ev->screenPos()); + return QGestureRecognizer::FinishGesture | QGestureRecognizer::ConsumeEventHint; + break; } + default: + break; + } + } + + return QGestureRecognizer::Ignore; +} + +void QMacSwipeGestureRecognizer::reset(QGesture *gesture) +{ + QSwipeGesture *g = static_cast(gesture); + g->setSwipeAngle(0); + QGestureRecognizer::reset(gesture); +} + +//////////////////////////////////////////////////////////////////////// + +QMacPinchGestureRecognizer::QMacPinchGestureRecognizer() +{ +} + +QGesture *QMacPinchGestureRecognizer::create(QObject * /*target*/) +{ + return new QPinchGesture; +} + +QGestureRecognizer::Result +QMacPinchGestureRecognizer::recognize(QGesture *gesture, QObject *obj, QEvent *event) +{ + if (event->type() == QEvent::NativeGesture && obj->isWidgetType()) { + QPinchGesture *g = static_cast(gesture); + QNativeGestureEvent *ev = static_cast(event); + switch (ev->gestureType()) { + case Qt::BeginNativeGesture: + reset(gesture); + g->setStartCenterPoint(static_cast(obj)->mapFromGlobal(ev->screenPos().toPoint())); + g->setCenterPoint(g->startCenterPoint()); + g->setChangeFlags(QPinchGesture::CenterPointChanged); + g->setTotalChangeFlags(g->totalChangeFlags() | g->changeFlags()); + g->setHotSpot(ev->screenPos()); + return QGestureRecognizer::MayBeGesture | QGestureRecognizer::ConsumeEventHint; + case Qt::RotateNativeGesture: + g->setLastScaleFactor(g->scaleFactor()); + g->setLastRotationAngle(g->rotationAngle()); + g->setRotationAngle(g->rotationAngle() + ev->value()); + g->setChangeFlags(QPinchGesture::RotationAngleChanged); + g->setTotalChangeFlags(g->totalChangeFlags() | g->changeFlags()); + g->setHotSpot(ev->screenPos()); + return QGestureRecognizer::TriggerGesture | QGestureRecognizer::ConsumeEventHint; + case Qt::ZoomNativeGesture: + g->setLastScaleFactor(g->scaleFactor()); + g->setLastRotationAngle(g->rotationAngle()); + g->setScaleFactor(g->scaleFactor() * (1 + ev->value())); + g->setChangeFlags(QPinchGesture::ScaleFactorChanged); + g->setTotalChangeFlags(g->totalChangeFlags() | g->changeFlags()); + g->setHotSpot(ev->screenPos()); + return QGestureRecognizer::TriggerGesture | QGestureRecognizer::ConsumeEventHint; + case Qt::SmartZoomNativeGesture: + g->setLastScaleFactor(g->scaleFactor()); + g->setLastRotationAngle(g->rotationAngle()); + g->setScaleFactor(ev->value() ? 1.7f : 1.0f); + g->setChangeFlags(QPinchGesture::ScaleFactorChanged); + g->setTotalChangeFlags(g->totalChangeFlags() | g->changeFlags()); + g->setHotSpot(ev->screenPos()); + return QGestureRecognizer::TriggerGesture | QGestureRecognizer::ConsumeEventHint; + case Qt::EndNativeGesture: + return QGestureRecognizer::FinishGesture | QGestureRecognizer::ConsumeEventHint; + default: + break; + } + } + + return QGestureRecognizer::Ignore; +} + +void QMacPinchGestureRecognizer::reset(QGesture *gesture) +{ + QPinchGesture *g = static_cast(gesture); + g->setChangeFlags(0); + g->setTotalChangeFlags(0); + g->setScaleFactor(1.0f); + g->setTotalScaleFactor(1.0f); + g->setLastScaleFactor(1.0f); + g->setRotationAngle(0.0f); + g->setTotalRotationAngle(0.0f); + g->setLastRotationAngle(0.0f); + g->setCenterPoint(QPointF()); + g->setStartCenterPoint(QPointF()); + g->setLastCenterPoint(QPointF()); + QGestureRecognizer::reset(gesture); +} + +//////////////////////////////////////////////////////////////////////// + +QMacPanGestureRecognizer::QMacPanGestureRecognizer() : _panCanceled(true) +{ +} + +QGesture *QMacPanGestureRecognizer::create(QObject *target) +{ + if (!target) + return new QPanGesture; + + if (QWidget *w = qobject_cast(target)) { + w->setAttribute(Qt::WA_AcceptTouchEvents); + w->setAttribute(Qt::WA_TouchPadAcceptSingleTouchEvents); + return new QPanGesture; + } + return 0; +} + +QGestureRecognizer::Result +QMacPanGestureRecognizer::recognize(QGesture *gesture, QObject *target, QEvent *event) +{ + const int panBeginDelay = 300; + const int panBeginRadius = 3; + + QPanGesture *g = static_cast(gesture); + + switch (event->type()) { + case QEvent::TouchBegin: { + const QTouchEvent *ev = static_cast(event); + if (ev->touchPoints().size() == 1) { + reset(gesture); + _startPos = QCursor::pos(); + _panTimer.start(panBeginDelay, target); + _panCanceled = false; + return QGestureRecognizer::MayBeGesture; + } + break;} + case QEvent::TouchEnd: { + if (_panCanceled) + break; + + const QTouchEvent *ev = static_cast(event); + if (ev->touchPoints().size() == 1) + return QGestureRecognizer::FinishGesture; + break;} + case QEvent::TouchUpdate: { + if (_panCanceled) + break; + + const QTouchEvent *ev = static_cast(event); + if (ev->touchPoints().size() == 1) { + if (_panTimer.isActive()) { + // INVARIANT: Still in maybeGesture. Check if the user + // moved his finger so much that it makes sense to cancel the pan: + const QPointF p = QCursor::pos(); + if ((p - _startPos).manhattanLength() > panBeginRadius) { + _panCanceled = true; + _panTimer.stop(); + return QGestureRecognizer::CancelGesture; + } + } else { + const QPointF p = QCursor::pos(); + const QPointF posOffset = p - _startPos; + g->setLastOffset(g->offset()); + g->setOffset(QPointF(posOffset.x(), posOffset.y())); + g->setHotSpot(_startPos); + return QGestureRecognizer::TriggerGesture; + } + } else if (_panTimer.isActive()) { + // I only want to cancel the pan if the user is pressing + // more than one finger, and the pan hasn't started yet: + _panCanceled = true; + _panTimer.stop(); + return QGestureRecognizer::CancelGesture; + } + break;} + case QEvent::Timer: { + QTimerEvent *ev = static_cast(event); + if (ev->timerId() == _panTimer.timerId()) { + _panTimer.stop(); + if (_panCanceled) + break; + // Begin new pan session! + _startPos = QCursor::pos(); + g->setHotSpot(_startPos); + return QGestureRecognizer::TriggerGesture | QGestureRecognizer::ConsumeEventHint; + } + break; } + default: + break; + } + + return QGestureRecognizer::Ignore; +} + +void QMacPanGestureRecognizer::reset(QGesture *gesture) +{ + QPanGesture *g = static_cast(gesture); + _startPos = QPointF(); + _panCanceled = true; + g->setOffset(QPointF(0, 0)); + g->setLastOffset(QPointF(0, 0)); + g->setAcceleration(qreal(1)); + QGestureRecognizer::reset(gesture); +} + +QT_END_NAMESPACE + +#endif // QT_NO_GESTURES diff --git a/src/widgets/kernel/qmacgesturerecognizer_p.h b/src/widgets/kernel/qmacgesturerecognizer_p.h new file mode 100644 index 0000000000..02f836b3f7 --- /dev/null +++ b/src/widgets/kernel/qmacgesturerecognizer_p.h @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtWidgets module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QMACSWIPEGESTURERECOGNIZER_MAC_P_H +#define QMACSWIPEGESTURERECOGNIZER_MAC_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qtimer.h" +#include "qpoint.h" +#include "qgesturerecognizer.h" + +#ifndef QT_NO_GESTURES + +QT_BEGIN_NAMESPACE + +class QMacSwipeGestureRecognizer : public QGestureRecognizer +{ +public: + QMacSwipeGestureRecognizer(); + + QGesture *create(QObject *target); + QGestureRecognizer::Result recognize(QGesture *gesture, QObject *watched, QEvent *event); + void reset(QGesture *gesture); +}; + +class QMacPinchGestureRecognizer : public QGestureRecognizer +{ +public: + QMacPinchGestureRecognizer(); + + QGesture *create(QObject *target); + QGestureRecognizer::Result recognize(QGesture *gesture, QObject *watched, QEvent *event); + void reset(QGesture *gesture); +}; + +class QMacPanGestureRecognizer : public QObject, public QGestureRecognizer +{ +public: + QMacPanGestureRecognizer(); + + QGesture *create(QObject *target); + QGestureRecognizer::Result recognize(QGesture *gesture, QObject *watched, QEvent *event); + void reset(QGesture *gesture); +private: + QPointF _startPos; + QBasicTimer _panTimer; + bool _panCanceled; +}; + +QT_END_NAMESPACE + +#endif // QT_NO_GESTURES + +#endif // QMACSWIPEGESTURERECOGNIZER_MAC_P_H diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index f2bd389769..668d5b0fc0 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -49,6 +49,7 @@ #endif #include #include +#include QT_BEGIN_NAMESPACE @@ -220,6 +221,13 @@ bool QWidgetWindow::event(QEvent *event) handleTabletEvent(static_cast(event)); return true; #endif + +#ifndef QT_NO_GESTURES + case QEvent::NativeGesture: + handleGestureEvent(static_cast(event)); + return true; +#endif + #ifndef QT_NO_CONTEXTMENU case QEvent::ContextMenu: handleContextMenuEvent(static_cast(event)); @@ -732,6 +740,25 @@ void QWidgetWindow::handleTabletEvent(QTabletEvent *event) } #endif // QT_NO_TABLETEVENT +#ifndef QT_NO_GESTURES +void QWidgetWindow::handleGestureEvent(QNativeGestureEvent *e) +{ + // copy-pasted code to find correct widget follows: + QObject *receiver = 0; + if (QApplicationPrivate::inPopupMode()) { + QWidget *popup = QApplication::activePopupWidget(); + QWidget *popupFocusWidget = popup->focusWidget(); + receiver = popupFocusWidget ? popupFocusWidget : popup; + } + if (!receiver) + receiver = QApplication::widgetAt(e->globalPos()); + if (!receiver) + receiver = m_widget; // last resort + + QApplication::sendSpontaneousEvent(receiver, e); +} +#endif // QT_NO_GESTURES + #ifndef QT_NO_CONTEXTMENU void QWidgetWindow::handleContextMenuEvent(QContextMenuEvent *e) { diff --git a/src/widgets/kernel/qwidgetwindow_qpa_p.h b/src/widgets/kernel/qwidgetwindow_qpa_p.h index cb7bef8f3e..341aaba0d5 100644 --- a/src/widgets/kernel/qwidgetwindow_qpa_p.h +++ b/src/widgets/kernel/qwidgetwindow_qpa_p.h @@ -91,6 +91,9 @@ protected: #ifndef QT_NO_TABLETEVENT void handleTabletEvent(QTabletEvent *); #endif +#ifndef QT_NO_GESTURES + void handleGestureEvent(QNativeGestureEvent *); +#endif #ifndef QT_NO_CONTEXTMENU void handleContextMenuEvent(QContextMenuEvent *); #endif -- cgit v1.2.3 From c3bf3bd8b74187b44ec91582e1cf2be546a73349 Mon Sep 17 00:00:00 2001 From: Samuel Gaist Date: Thu, 10 Oct 2013 16:32:31 +0200 Subject: Properly paint QListView dragged item in icon mode Currently, when dragging a QListView item in icon mode, only the item is moved and once out of the view port, the visual feedback is lost. This patch updates the QDrag pixmap to have a persistent view of what is moved. Task-number: QTBUG-1180 [ChangeLog][QtWidgets][QTBUG-1180] Dragging an item outside the QListView in icon mode doesn't lose the icon. Change-Id: I14f864a8f947997f3bdad1a05fabd200de026d66 Reviewed-by: Stephen Kelly --- src/widgets/itemviews/qlistview.cpp | 40 +++++++++++++++---------------------- src/widgets/itemviews/qlistview_p.h | 5 +---- 2 files changed, 17 insertions(+), 28 deletions(-) diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp index e5a8647f87..43632c5fa9 100644 --- a/src/widgets/itemviews/qlistview.cpp +++ b/src/widgets/itemviews/qlistview.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2013 Samuel Gaist ** Contact: http://www.qt-project.org/legal ** ** This file is part of the QtWidgets module of the Qt Toolkit. @@ -1833,6 +1834,15 @@ void QCommonListViewBase::removeHiddenRow(int row) dd->hiddenRows.remove(dd->model->index(row, 0, qq->rootIndex())); } +#ifndef QT_NO_DRAGANDDROP +void QCommonListViewBase::paintDragDrop(QPainter *painter) +{ + // FIXME: Until the we can provide a proper drop indicator + // in IconMode, it makes no sense to show it + dd->paintDropIndicator(painter); +} +#endif + void QCommonListViewBase::updateHorizontalScrollBar(const QSize & /*step*/) { horizontalScrollBar()->setPageStep(viewport()->width()); @@ -1902,13 +1912,6 @@ int QCommonListViewBase::horizontalScrollToValue(const int /*index*/, QListView: */ #ifndef QT_NO_DRAGANDDROP -void QListModeViewBase::paintDragDrop(QPainter *painter) -{ - // FIXME: Until the we can provide a proper drop indicator - // in IconMode, it makes no sense to show it - dd->paintDropIndicator(painter); -} - QAbstractItemView::DropIndicatorPosition QListModeViewBase::position(const QPoint &pos, const QRect &rect, const QModelIndex &index) const { QAbstractItemView::DropIndicatorPosition r = QAbstractItemView::OnViewport; @@ -2651,23 +2654,6 @@ void QIconModeViewBase::removeHiddenRow(int row) } #ifndef QT_NO_DRAGANDDROP -void QIconModeViewBase::paintDragDrop(QPainter *painter) -{ - if (!draggedItems.isEmpty() && viewport()->rect().contains(draggedItemsPos)) { - //we need to draw the items that arre dragged - painter->translate(draggedItemsDelta()); - QStyleOptionViewItem option = viewOptions(); - option.state &= ~QStyle::State_MouseOver; - QVector::const_iterator it = draggedItems.constBegin(); - QListViewItem item = indexToListViewItem(*it); - for (; it != draggedItems.constEnd(); ++it) { - item = indexToListViewItem(*it); - option.rect = viewItemRect(item); - delegate(*it)->paint(painter, option, *it); - } - } -} - bool QIconModeViewBase::filterStartDrag(Qt::DropActions supportedActions) { // This function does the same thing as in QAbstractItemView::startDrag(), @@ -2682,8 +2668,14 @@ bool QIconModeViewBase::filterStartDrag(Qt::DropActions supportedActions) && (*it).column() == dd->column) draggedItems.push_back(*it); } + + QRect rect; + QPixmap pixmap = dd->renderToPixmap(indexes, &rect); + rect.adjust(horizontalOffset(), verticalOffset(), 0, 0); QDrag *drag = new QDrag(qq); drag->setMimeData(dd->model->mimeData(indexes)); + drag->setPixmap(pixmap); + drag->setHotSpot(dd->pressedPosition - rect.topLeft()); Qt::DropAction action = drag->exec(supportedActions, Qt::CopyAction); draggedItems.clear(); if (action == Qt::MoveAction) diff --git a/src/widgets/itemviews/qlistview_p.h b/src/widgets/itemviews/qlistview_p.h index 35d11140ef..3d39061bdb 100644 --- a/src/widgets/itemviews/qlistview_p.h +++ b/src/widgets/itemviews/qlistview_p.h @@ -147,7 +147,7 @@ public: virtual void setPositionForIndex(const QPoint &, const QModelIndex &) { } #ifndef QT_NO_DRAGANDDROP - virtual void paintDragDrop(QPainter *painter) = 0; + virtual void paintDragDrop(QPainter *painter); virtual bool filterDragMoveEvent(QDragMoveEvent *) { return false; } virtual bool filterDragLeaveEvent(QDragLeaveEvent *) { return false; } virtual bool filterDropEvent(QDropEvent *) { return false; } @@ -231,8 +231,6 @@ public: void updateVerticalScrollBar(const QSize &step); #ifndef QT_NO_DRAGANDDROP - void paintDragDrop(QPainter *painter); - // The next two methods are to be used on LefToRight flow only. // WARNING: Plenty of duplicated code from QAbstractItemView{,Private}. QAbstractItemView::DropIndicatorPosition position(const QPoint &pos, const QRect &rect, const QModelIndex &idx) const; @@ -279,7 +277,6 @@ public: void setPositionForIndex(const QPoint &position, const QModelIndex &index); #ifndef QT_NO_DRAGANDDROP - void paintDragDrop(QPainter *painter); bool filterDragMoveEvent(QDragMoveEvent *); bool filterDragLeaveEvent(QDragLeaveEvent *); bool filterDropEvent(QDropEvent *e); -- cgit v1.2.3 From b329c8ffb960da492d90c7bf70ed93f23fa2d400 Mon Sep 17 00:00:00 2001 From: Samuel Gaist Date: Thu, 17 Oct 2013 14:10:46 +0200 Subject: Move the viewOptions code back to public implementation The code generating the QStyleOptionViewItem has been moved back to the public implementation and the private QAbstractItemView::viewOptions calling it (like the Qt 4 implementation does). This makes the item views behave properly again e.g. QListView drag & drop in Icon mode gets the correct options to draw the moving items Task-number: QTBUG-1180 Change-Id: I068861e1485252f12d73f9acaf12933d0ec84e2c Reviewed-by: Stephen Kelly --- src/widgets/itemviews/qabstractitemview.cpp | 34 ++++++++++++++--------------- src/widgets/itemviews/qlistview.cpp | 18 +++++---------- src/widgets/itemviews/qlistview_p.h | 2 -- src/widgets/itemviews/qtableview.cpp | 12 +++------- src/widgets/itemviews/qtableview_p.h | 2 -- 5 files changed, 26 insertions(+), 42 deletions(-) diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp index 35ba1ed74e..d3e6b7ab52 100644 --- a/src/widgets/itemviews/qabstractitemview.cpp +++ b/src/widgets/itemviews/qabstractitemview.cpp @@ -3600,45 +3600,45 @@ void QAbstractItemView::startDrag(Qt::DropActions supportedActions) QStyleOptionViewItem QAbstractItemView::viewOptions() const { Q_D(const QAbstractItemView); - return d->viewOptions(); -} - -QStyleOptionViewItem QAbstractItemViewPrivate::viewOptions() const -{ - Q_Q(const QAbstractItemView); QStyleOptionViewItem option; - option.init(q); + option.init(this); option.state &= ~QStyle::State_MouseOver; - option.font = q->font(); + option.font = font(); #ifndef Q_WS_MAC // On mac the focus appearance follows window activation // not widget activation - if (!q->hasFocus()) + if (!hasFocus()) option.state &= ~QStyle::State_Active; #endif option.state &= ~QStyle::State_HasFocus; - if (iconSize.isValid()) { - option.decorationSize = iconSize; + if (d->iconSize.isValid()) { + option.decorationSize = d->iconSize; } else { - int pm = q->style()->pixelMetric(QStyle::PM_SmallIconSize, 0, q); + int pm = style()->pixelMetric(QStyle::PM_SmallIconSize, 0, this); option.decorationSize = QSize(pm, pm); } option.decorationPosition = QStyleOptionViewItem::Left; option.decorationAlignment = Qt::AlignCenter; option.displayAlignment = Qt::AlignLeft|Qt::AlignVCenter; - option.textElideMode = textElideMode; + option.textElideMode = d->textElideMode; option.rect = QRect(); - option.showDecorationSelected = q->style()->styleHint(QStyle::SH_ItemView_ShowDecorationSelected, 0, q); - if (wrapItemText) + option.showDecorationSelected = style()->styleHint(QStyle::SH_ItemView_ShowDecorationSelected, 0, this); + if (d->wrapItemText) option.features = QStyleOptionViewItem::WrapText; - option.locale = q->locale(); + option.locale = locale(); option.locale.setNumberOptions(QLocale::OmitGroupSeparator); - option.widget = q; + option.widget = this; return option; } +QStyleOptionViewItem QAbstractItemViewPrivate::viewOptions() const +{ + Q_Q(const QAbstractItemView); + return q->viewOptions(); +} + /*! Returns the item view's state. diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp index 43632c5fa9..8785348d2b 100644 --- a/src/widgets/itemviews/qlistview.cpp +++ b/src/widgets/itemviews/qlistview.cpp @@ -901,20 +901,14 @@ void QListView::startDrag(Qt::DropActions supportedActions) QStyleOptionViewItem QListView::viewOptions() const { Q_D(const QListView); - return d->viewOptions(); -} - -QStyleOptionViewItem QListViewPrivate::viewOptions() const -{ - Q_Q(const QListView); - QStyleOptionViewItem option = QAbstractItemViewPrivate::viewOptions(); - if (!iconSize.isValid()) { // otherwise it was already set in abstractitemview - int pm = (viewMode == QListView::ListMode - ? q->style()->pixelMetric(QStyle::PM_ListViewIconSize, 0, q) - : q->style()->pixelMetric(QStyle::PM_IconViewIconSize, 0, q)); + QStyleOptionViewItem option = QAbstractItemView::viewOptions(); + if (!d->iconSize.isValid()) { // otherwise it was already set in abstractitemview + int pm = (d->viewMode == QListView::ListMode + ? style()->pixelMetric(QStyle::PM_ListViewIconSize, 0, this) + : style()->pixelMetric(QStyle::PM_IconViewIconSize, 0, this)); option.decorationSize = QSize(pm, pm); } - if (viewMode == QListView::IconMode) { + if (d->viewMode == QListView::IconMode) { option.showDecorationSelected = false; option.decorationPosition = QStyleOptionViewItem::Top; option.displayAlignment = Qt::AlignCenter; diff --git a/src/widgets/itemviews/qlistview_p.h b/src/widgets/itemviews/qlistview_p.h index 3d39061bdb..2edbbaae19 100644 --- a/src/widgets/itemviews/qlistview_p.h +++ b/src/widgets/itemviews/qlistview_p.h @@ -391,8 +391,6 @@ public: } } - QStyleOptionViewItem viewOptions() const; - void scrollElasticBandBy(int dx, int dy); QItemViewPaintPairs draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const; diff --git a/src/widgets/itemviews/qtableview.cpp b/src/widgets/itemviews/qtableview.cpp index 34e881571e..2aff170732 100644 --- a/src/widgets/itemviews/qtableview.cpp +++ b/src/widgets/itemviews/qtableview.cpp @@ -1346,20 +1346,14 @@ void QTableView::scrollContentsBy(int dx, int dy) } } -QStyleOptionViewItem QTableViewPrivate::viewOptions() const -{ - QStyleOptionViewItem option = QAbstractItemViewPrivate::viewOptions(); - option.showDecorationSelected = true; - return option; -} - /*! \reimp */ QStyleOptionViewItem QTableView::viewOptions() const { - Q_D(const QTableView); - return d->viewOptions(); + QStyleOptionViewItem option = QAbstractItemView::viewOptions(); + option.showDecorationSelected = true; + return option; } /*! diff --git a/src/widgets/itemviews/qtableview_p.h b/src/widgets/itemviews/qtableview_p.h index 74eb7b7728..555ae50daf 100644 --- a/src/widgets/itemviews/qtableview_p.h +++ b/src/widgets/itemviews/qtableview_p.h @@ -150,8 +150,6 @@ public: void init(); void trimHiddenSelections(QItemSelectionRange *range) const; - QStyleOptionViewItem viewOptions() const; - inline bool isHidden(int row, int col) const { return verticalHeader->isSectionHidden(row) || horizontalHeader->isSectionHidden(col); -- cgit v1.2.3 From e7cf7c1c65ff2379621603742f2b9ae344e40f69 Mon Sep 17 00:00:00 2001 From: Nick Ratelle Date: Wed, 16 Oct 2013 13:24:32 -0400 Subject: Blackberry: Cannot create shared egl contexts. Currently the share context is always set to EGL_NO_CONTEXT when it should instead query the share handle from the QOpenGlContext and pass that to the eglCreateContext call. Change-Id: Ia7e32574e1427fba0f919003e5367cfc98688d9d Reviewed-by: Sean Harmer --- src/plugins/platforms/qnx/qqnxglcontext.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/qnx/qqnxglcontext.cpp b/src/plugins/platforms/qnx/qqnxglcontext.cpp index 355f52c46e..34e8150928 100644 --- a/src/plugins/platforms/qnx/qqnxglcontext.cpp +++ b/src/plugins/platforms/qnx/qqnxglcontext.cpp @@ -124,7 +124,15 @@ QQnxGLContext::QQnxGLContext(QOpenGLContext *glContext) if (m_eglConfig == 0) qFatal("QQnxGLContext: failed to find EGL config"); - m_eglContext = eglCreateContext(ms_eglDisplay, m_eglConfig, EGL_NO_CONTEXT, contextAttrs()); + EGLContext shareContext = EGL_NO_CONTEXT; + if (m_glContext) { + QQnxGLContext *qshareContext = dynamic_cast(m_glContext->shareHandle()); + if (qshareContext) { + shareContext = qshareContext->m_eglContext; + } + } + + m_eglContext = eglCreateContext(ms_eglDisplay, m_eglConfig, shareContext, contextAttrs()); if (m_eglContext == EGL_NO_CONTEXT) { checkEGLError("eglCreateContext"); qFatal("QQnxGLContext: failed to create EGL context, err=%d", eglGetError()); -- cgit v1.2.3 From 39eb7e0b898da9302afa23087913af45844135b5 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 16 Oct 2013 15:32:48 +0200 Subject: Refresh CUPS printer list when QPrinterInfo.availablePrinters() is called. Introduce freeCupsPrinters() thus fixing a bug in the old deallocation code which would first set m_cupsPrintersCount = 0 and then pass it to cupsFreeDests(). Task-number: QTBUG-33666 Change-Id: I94c51cb390761a669a9cbd589c1131cfb51354c3 Reviewed-by: Lars Knoll --- .../printsupport/cups/qcupsprintersupport.cpp | 23 ++++++++++++++++------ .../printsupport/cups/qcupsprintersupport_p.h | 2 ++ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/plugins/printsupport/cups/qcupsprintersupport.cpp b/src/plugins/printsupport/cups/qcupsprintersupport.cpp index f41d4f5047..b9f0c394f8 100644 --- a/src/plugins/printsupport/cups/qcupsprintersupport.cpp +++ b/src/plugins/printsupport/cups/qcupsprintersupport.cpp @@ -66,8 +66,7 @@ QCupsPrinterSupport::QCupsPrinterSupport() : QPlatformPrinterSupport(), QCupsPrinterSupport::~QCupsPrinterSupport() { - if (cupsFreeDests) - cupsFreeDests(m_cupsPrintersCount, m_cupsPrinters); + freeCupsPrinters(); } QPrintEngine *QCupsPrinterSupport::createNativePrintEngine(QPrinter::PrinterMode printerMode) @@ -98,14 +97,20 @@ void QCupsPrinterSupport::loadCups() cupsGetOption = (CupsGetOption) m_cups.resolve("cupsGetOption"); } +void QCupsPrinterSupport::freeCupsPrinters() +{ + if (cupsFreeDests && m_cupsPrintersCount) { + cupsFreeDests(m_cupsPrintersCount, m_cupsPrinters); + m_cupsPrintersCount = 0; + m_cupsPrinters = 0; + } +} + void QCupsPrinterSupport::loadCupsPrinters() { - m_cupsPrintersCount = 0; + freeCupsPrinters(); m_printers.clear(); - if (cupsFreeDests) - cupsFreeDests(m_cupsPrintersCount, m_cupsPrinters); - if (cupsGetDests) m_cupsPrintersCount = cupsGetDests(&m_cupsPrinters); @@ -122,6 +127,12 @@ void QCupsPrinterSupport::loadCupsPrinters() } } +QList QCupsPrinterSupport::availablePrinters() +{ + loadCupsPrinters(); + return QPlatformPrinterSupport::availablePrinters(); +} + QString QCupsPrinterSupport::printerOption(const QPrinterInfo &printer, const QString &key) const { return cupsOption(printerIndex(printer), key); diff --git a/src/plugins/printsupport/cups/qcupsprintersupport_p.h b/src/plugins/printsupport/cups/qcupsprintersupport_p.h index e9fe24203e..d42c0d2630 100644 --- a/src/plugins/printsupport/cups/qcupsprintersupport_p.h +++ b/src/plugins/printsupport/cups/qcupsprintersupport_p.h @@ -68,12 +68,14 @@ public: virtual QPaintEngine *createPaintEngine(QPrintEngine *printEngine, QPrinter::PrinterMode); virtual QList supportedPaperSizes(const QPrinterInfo &) const; virtual QList > supportedSizesWithNames(const QPrinterInfo &) const; + virtual QList availablePrinters(); virtual QString printerOption(const QPrinterInfo &printer, const QString &key) const; virtual PrinterOptions printerOptions(const QPrinterInfo &printer) const; private: void loadCups(); void loadCupsPrinters(); + void freeCupsPrinters(); QString cupsOption(int i, const QString &key) const; QLibrary m_cups; -- cgit v1.2.3 From 1d3fce8b509fdb7d71f8e40ef9ed720f4dc69202 Mon Sep 17 00:00:00 2001 From: hjk Date: Sat, 12 Oct 2013 10:54:37 +0200 Subject: Add missing \since 5.2 tag to static QFileInfo::exists() Change-Id: I11e136eaede2a5dffeb10b5fe31023b9aef709cb Reviewed-by: Sze Howe Koh Reviewed-by: Kai Koehne --- src/corelib/io/qfileinfo.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp index 1c216f8a6b..897af352c9 100644 --- a/src/corelib/io/qfileinfo.cpp +++ b/src/corelib/io/qfileinfo.cpp @@ -675,6 +675,8 @@ bool QFileInfo::exists() const } /*! + \since 5.2 + Returns \c true if the \a file exists; otherwise returns \c false. \note If \a file is a symlink that points to a non-existing -- cgit v1.2.3 From cc3ece1da4f1d6b8742805770f18488183f8ad02 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Thu, 17 Oct 2013 14:45:13 +0200 Subject: evdevtouch: Make it work with am335x The driver for the resistive touchscreen of these boards tends to report ABS limits 0..4095 even tough it never sends coordinates outside a certain range (e.g. approximately 165..4016 for X). This breaks the mapping of hardware coordinates to screen space. Apply a workaround to make it work properly. Change-Id: I3eb5d76002acba1972061f3add44d797349c8ec8 Reviewed-by: Andy Nichols --- src/platformsupport/input/evdevtouch/qevdevtouch.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/platformsupport/input/evdevtouch/qevdevtouch.cpp b/src/platformsupport/input/evdevtouch/qevdevtouch.cpp index 3b79a2ac80..89215557c1 100644 --- a/src/platformsupport/input/evdevtouch/qevdevtouch.cpp +++ b/src/platformsupport/input/evdevtouch/qevdevtouch.cpp @@ -300,6 +300,21 @@ QEvdevTouchScreenHandler::QEvdevTouchScreenHandler(const QString &specification, qDebug("evdevtouch: device name: %s", name); } + // Fix up the coordinate ranges for am335x in case the kernel driver does not have them fixed. + if (d->hw_name == QLatin1String("ti-tsc")) { + if (d->hw_range_x_min == 0 && d->hw_range_x_max == 4095) { + d->hw_range_x_min = 165; + d->hw_range_x_max = 4016; + } + if (d->hw_range_y_min == 0 && d->hw_range_y_max == 4095) { + d->hw_range_y_min = 220; + d->hw_range_y_max = 3907; + } + if (printDeviceInfo) + qDebug("evdevtouch: found ti-tsc, overriding: min X: %d max X: %d min Y: %d max Y: %d", + d->hw_range_x_min, d->hw_range_x_max, d->hw_range_y_min, d->hw_range_y_max); + } + bool grabSuccess = !ioctl(m_fd, EVIOCGRAB, (void *) 1); if (grabSuccess) ioctl(m_fd, EVIOCGRAB, (void *) 0); -- cgit v1.2.3 From 72544a5142b19454f9636c567ba199161c02e79b Mon Sep 17 00:00:00 2001 From: Samuel Gaist Date: Thu, 10 Oct 2013 16:43:44 +0200 Subject: Rename private viewOptions to viewOptionsV1 Renaming of the private implementation of viewOptions to viewOptionsV1 so that future updates of QStyleOptionViewItem can be easily integrated in the code with a simple search/replace. Task-number: QTBUG-1180 Change-Id: I18f876a435417717fa0d759bb302a7c6059daf80 Reviewed-by: Stephen Kelly --- src/widgets/itemviews/qabstractitemview.cpp | 22 +++++++++++----------- src/widgets/itemviews/qabstractitemview_p.h | 2 +- src/widgets/itemviews/qlistview.cpp | 4 ++-- src/widgets/itemviews/qlistview_p.h | 2 +- src/widgets/itemviews/qtableview.cpp | 6 +++--- src/widgets/itemviews/qtreeview.cpp | 8 ++++---- 6 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp index d3e6b7ab52..726c2704c4 100644 --- a/src/widgets/itemviews/qabstractitemview.cpp +++ b/src/widgets/itemviews/qabstractitemview.cpp @@ -1651,7 +1651,7 @@ bool QAbstractItemView::viewportEvent(QEvent *event) case QEvent::WhatsThis: { QHelpEvent *he = static_cast(event); const QModelIndex index = indexAt(he->pos()); - QStyleOptionViewItem option = d->viewOptions(); + QStyleOptionViewItem option = d->viewOptionsV1(); option.rect = visualRect(index); option.state |= (index == currentIndex() ? QStyle::State_HasFocus : QStyle::State_None); @@ -1851,7 +1851,7 @@ void QAbstractItemView::mouseReleaseEvent(QMouseEvent *event) emit clicked(index); if (edited) return; - QStyleOptionViewItem option = d->viewOptions(); + QStyleOptionViewItem option = d->viewOptionsV1(); if (d->pressedAlreadySelected) option.state |= QStyle::State_Selected; if ((model()->flags(index) & Qt::ItemIsEnabled) @@ -2627,7 +2627,7 @@ void QAbstractItemView::updateEditorGeometries() Q_D(QAbstractItemView); if(d->editorIndexHash.isEmpty()) return; - QStyleOptionViewItem option = d->viewOptions(); + QStyleOptionViewItem option = d->viewOptionsV1(); QEditorIndexHash::iterator it = d->editorIndexHash.begin(); QWidgetList editorsToRelease; QWidgetList editorsToHide; @@ -2972,7 +2972,7 @@ QSize QAbstractItemView::sizeHintForIndex(const QModelIndex &index) const Q_D(const QAbstractItemView); if (!d->isIndexValid(index) || !d->itemDelegate) return QSize(); - return d->delegateForIndex(index)->sizeHint(d->viewOptions(), index); + return d->delegateForIndex(index)->sizeHint(d->viewOptionsV1(), index); } /*! @@ -3000,7 +3000,7 @@ int QAbstractItemView::sizeHintForRow(int row) const ensurePolished(); - QStyleOptionViewItem option = d->viewOptions(); + QStyleOptionViewItem option = d->viewOptionsV1(); int height = 0; int colCount = d->model->columnCount(d->root); QModelIndex index; @@ -3031,7 +3031,7 @@ int QAbstractItemView::sizeHintForColumn(int column) const ensurePolished(); - QStyleOptionViewItem option = d->viewOptions(); + QStyleOptionViewItem option = d->viewOptionsV1(); int width = 0; int rows = d->model->rowCount(d->root); QModelIndex index; @@ -3054,7 +3054,7 @@ int QAbstractItemView::sizeHintForColumn(int column) const void QAbstractItemView::openPersistentEditor(const QModelIndex &index) { Q_D(QAbstractItemView); - QStyleOptionViewItem options = d->viewOptions(); + QStyleOptionViewItem options = d->viewOptionsV1(); options.rect = visualRect(index); options.state |= (index == currentIndex() ? QStyle::State_HasFocus : QStyle::State_None); @@ -3633,7 +3633,7 @@ QStyleOptionViewItem QAbstractItemView::viewOptions() const return option; } -QStyleOptionViewItem QAbstractItemViewPrivate::viewOptions() const +QStyleOptionViewItem QAbstractItemViewPrivate::viewOptionsV1() const { Q_Q(const QAbstractItemView); return q->viewOptions(); @@ -4274,7 +4274,7 @@ bool QAbstractItemViewPrivate::sendDelegateEvent(const QModelIndex &index, QEven { Q_Q(const QAbstractItemView); QModelIndex buddy = model->buddy(index); - QStyleOptionViewItem options = viewOptions(); + QStyleOptionViewItem options = viewOptionsV1(); options.rect = q->visualRect(buddy); options.state |= (buddy == q->currentIndex() ? QStyle::State_HasFocus : QStyle::State_None); QAbstractItemDelegate *delegate = delegateForIndex(index); @@ -4286,7 +4286,7 @@ bool QAbstractItemViewPrivate::openEditor(const QModelIndex &index, QEvent *even Q_Q(QAbstractItemView); QModelIndex buddy = model->buddy(index); - QStyleOptionViewItem options = viewOptions(); + QStyleOptionViewItem options = viewOptionsV1(); options.rect = q->visualRect(buddy); options.state |= (buddy == q->currentIndex() ? QStyle::State_HasFocus : QStyle::State_None); @@ -4338,7 +4338,7 @@ QPixmap QAbstractItemViewPrivate::renderToPixmap(const QModelIndexList &indexes, QPixmap pixmap(r->size()); pixmap.fill(Qt::transparent); QPainter painter(&pixmap); - QStyleOptionViewItem option = viewOptions(); + QStyleOptionViewItem option = viewOptionsV1(); option.state |= QStyle::State_Selected; for (int j = 0; j < paintPairs.count(); ++j) { option.rect = paintPairs.at(j).first.translated(-r->topLeft()); diff --git a/src/widgets/itemviews/qabstractitemview_p.h b/src/widgets/itemviews/qabstractitemview_p.h index 5da22615e2..1b5987de16 100644 --- a/src/widgets/itemviews/qabstractitemview_p.h +++ b/src/widgets/itemviews/qabstractitemview_p.h @@ -347,7 +347,7 @@ public: QModelIndexList selectedDraggableIndexes() const; - QStyleOptionViewItem viewOptions() const; + QStyleOptionViewItem viewOptionsV1() const; void doDelayedReset() { diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp index 8785348d2b..616a832b88 100644 --- a/src/widgets/itemviews/qlistview.cpp +++ b/src/widgets/itemviews/qlistview.cpp @@ -927,7 +927,7 @@ void QListView::paintEvent(QPaintEvent *e) Q_D(QListView); if (!d->itemDelegate) return; - QStyleOptionViewItem option = d->viewOptions(); + QStyleOptionViewItem option = d->viewOptionsV1(); QPainter painter(d->viewport); const QVector toBeRendered = d->intersectingSet(e->rect().translated(horizontalOffset(), verticalOffset()), false); @@ -1456,7 +1456,7 @@ void QListView::updateGeometries() verticalScrollBar()->setRange(0, 0); } else { QModelIndex index = d->model->index(0, d->column, d->root); - QStyleOptionViewItem option = d->viewOptions(); + QStyleOptionViewItem option = d->viewOptionsV1(); QSize step = d->itemSize(option, index); d->commonListView->updateHorizontalScrollBar(step); d->commonListView->updateVerticalScrollBar(step); diff --git a/src/widgets/itemviews/qlistview_p.h b/src/widgets/itemviews/qlistview_p.h index 2edbbaae19..4f3ccedb62 100644 --- a/src/widgets/itemviews/qlistview_p.h +++ b/src/widgets/itemviews/qlistview_p.h @@ -465,7 +465,7 @@ inline QModelIndex QCommonListViewBase::modelIndex(int row) const { return dd->model->index(row, dd->column, dd->root); } inline int QCommonListViewBase::rowCount() const { return dd->model->rowCount(dd->root); } -inline QStyleOptionViewItem QCommonListViewBase::viewOptions() const { return dd->viewOptions(); } +inline QStyleOptionViewItem QCommonListViewBase::viewOptions() const { return dd->viewOptionsV1(); } inline QWidget *QCommonListViewBase::viewport() const { return dd->viewport; } inline QRect QCommonListViewBase::clipRect() const { return dd->clipRect(); } diff --git a/src/widgets/itemviews/qtableview.cpp b/src/widgets/itemviews/qtableview.cpp index 2aff170732..08600b3ef7 100644 --- a/src/widgets/itemviews/qtableview.cpp +++ b/src/widgets/itemviews/qtableview.cpp @@ -1363,7 +1363,7 @@ void QTableView::paintEvent(QPaintEvent *event) { Q_D(QTableView); // setup temp variables for the painting - QStyleOptionViewItem option = d->viewOptions(); + QStyleOptionViewItem option = d->viewOptionsV1(); const QPoint offset = d->scrollDelayOffset; const bool showGrid = d->showGrid; const int gridSize = showGrid ? 1 : 0; @@ -2235,7 +2235,7 @@ int QTableView::sizeHintForRow(int row) const if (right == -1) // the table don't have enough columns to fill the viewport right = d->model->columnCount(d->root) - 1; - QStyleOptionViewItem option = d->viewOptions(); + QStyleOptionViewItem option = d->viewOptionsV1(); int hint = 0; QModelIndex index; @@ -2323,7 +2323,7 @@ int QTableView::sizeHintForColumn(int column) const if (!isVisible() || bottom == -1) // the table don't have enough rows to fill the viewport bottom = d->model->rowCount(d->root) - 1; - QStyleOptionViewItem option = d->viewOptions(); + QStyleOptionViewItem option = d->viewOptionsV1(); int hint = 0; int rowsProcessed = 0; diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp index 22cd9abc73..792b75ac69 100644 --- a/src/widgets/itemviews/qtreeview.cpp +++ b/src/widgets/itemviews/qtreeview.cpp @@ -1441,7 +1441,7 @@ void QTreeView::drawTree(QPainter *painter, const QRegion ®ion) const Q_D(const QTreeView); const QVector viewItems = d->viewItems; - QStyleOptionViewItem option = d->viewOptions(); + QStyleOptionViewItem option = d->viewOptionsV1(); const QStyle::State state = option.state; d->current = 0; @@ -2850,7 +2850,7 @@ int QTreeView::sizeHintForColumn(int column) const return -1; ensurePolished(); int w = 0; - QStyleOptionViewItem option = d->viewOptions(); + QStyleOptionViewItem option = d->viewOptionsV1(); const QVector viewItems = d->viewItems; const int maximumProcessRows = d->header->resizeContentsPrecision(); // To avoid this to take forever. @@ -2947,7 +2947,7 @@ int QTreeView::indexRowSizeHint(const QModelIndex &index) const qSwap(end, start); int height = -1; - QStyleOptionViewItem option = d->viewOptions(); + QStyleOptionViewItem option = d->viewOptionsV1(); // ### If we want word wrapping in the items, // ### we need to go through all the columns // ### and set the width of the column @@ -3220,7 +3220,7 @@ QPixmap QTreeViewPrivate::renderTreeToPixmapForAnimation(const QRect &rect) cons painter.end(); //and now let's render the editors the editors - QStyleOptionViewItem option = viewOptions(); + QStyleOptionViewItem option = viewOptionsV1(); for (QEditorIndexHash::const_iterator it = editorIndexHash.constBegin(); it != editorIndexHash.constEnd(); ++it) { QWidget *editor = it.key(); const QModelIndex &index = it.value(); -- cgit v1.2.3 From 93f5e0598ad2c7738409eb027fc868ab35db5920 Mon Sep 17 00:00:00 2001 From: John Layt Date: Thu, 17 Oct 2013 19:02:03 +0200 Subject: QDateTime - Fix RFC 2822 Date Formatting The RFC 2822 date format should always use en_US locale for month and day names instead of whatever the system locale is. Also remove some duplicate code. Change-Id: Ia2f7ee405b4e0e2f04980301783b9488628da73f Reviewed-by: Thiago Macieira --- src/corelib/tools/qdatetime.cpp | 28 +++------------------- .../auto/corelib/tools/qdatetime/tst_qdatetime.cpp | 4 ++++ 2 files changed, 7 insertions(+), 25 deletions(-) diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index dec4d9aaa4..5ce11a43aa 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -891,7 +891,7 @@ QString QDate::toString(Qt::DateFormat format) const case Qt::DefaultLocaleLongDate: return QLocale().toString(*this, QLocale::LongFormat); case Qt::RFC2822Date: - return toString(QStringLiteral("dd MMM yyyy")); + return QLocale::c().toString(*this, QStringLiteral("dd MMM yyyy")); default: #ifndef QT_NO_TEXTDATE case Qt::TextDate: @@ -1638,9 +1638,6 @@ QString QTime::toString(Qt::DateFormat format) const case Qt::DefaultLocaleLongDate: return QLocale().toString(*this, QLocale::LongFormat); case Qt::RFC2822Date: - return QString::fromLatin1("%1:%2:%3").arg(hour(), 2, 10, QLatin1Char('0')) - .arg(minute(), 2, 10, QLatin1Char('0')) - .arg(second(), 2, 10, QLatin1Char('0')); case Qt::ISODate: case Qt::TextDate: default: @@ -3548,27 +3545,8 @@ QString QDateTime::toString(Qt::DateFormat format) const case Qt::DefaultLocaleLongDate: return QLocale().toString(*this, QLocale::LongFormat); case Qt::RFC2822Date: { - buf = toString(QStringLiteral("dd MMM yyyy hh:mm:ss ")); - - int utcOffset = d->m_offsetFromUtc; - if (timeSpec() == Qt::LocalTime) { - QDateTime utc = toUTC(); - utc.setTimeSpec(timeSpec()); - utcOffset = utc.secsTo(*this); - } - - const int offset = qAbs(utcOffset); - buf += QLatin1Char((offset == utcOffset) ? '+' : '-'); - - const int hour = offset / 3600; - if (hour < 10) - buf += QLatin1Char('0'); - buf += QString::number(hour); - - const int min = (offset - (hour * 3600)) / 60; - if (min < 10) - buf += QLatin1Char('0'); - buf += QString::number(min); + buf = QLocale::c().toString(*this, QStringLiteral("dd MMM yyyy hh:mm:ss ")); + buf += toOffsetString(Qt::TextDate, d->m_offsetFromUtc); return buf; } default: diff --git a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp index 0c560df423..0ee40713aa 100644 --- a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp +++ b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp @@ -778,7 +778,11 @@ void tst_QDateTime::toString_rfcDate() QFETCH(QDateTime, dt); QFETCH(QString, formatted); + // Set to non-English locale to confirm still uses English + QLocale oldLocale; + QLocale::setDefault(QLocale("de_DE")); QCOMPARE(dt.toString(Qt::RFC2822Date), formatted); + QLocale::setDefault(oldLocale); } void tst_QDateTime::toString_enumformat() -- cgit v1.2.3 From c768b0a7af7dd1bb7dba2e124a2bb3c5df803f48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 15 Oct 2013 15:19:48 +0200 Subject: iOS: Prevent stray non-expected rules/targets in Xcode-wrapper makefile Change-Id: Ibef10ba174df25aa97fd986b51a62d6b7feb119e Reviewed-by: Oswald Buddenhagen Reviewed-by: Richard Moe Gustavsen --- mkspecs/macx-ios-clang/features/default_post.prf | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mkspecs/macx-ios-clang/features/default_post.prf b/mkspecs/macx-ios-clang/features/default_post.prf index a61db3daea..e8dc859de6 100644 --- a/mkspecs/macx-ios-clang/features/default_post.prf +++ b/mkspecs/macx-ios-clang/features/default_post.prf @@ -17,10 +17,13 @@ equals(TEMPLATE, app) { # building by calling out to xcodebuild. TEMPLATE = aux - CONFIG -= have_target qt staticlib dll + CONFIG = SOURCES = + OBJECTIVE_SOURCES = RESOURCES = INSTALLS = + QMAKE_EXTRA_COMPILERS = + QMAKE_EXTRA_TARGETS = TARGET_XCODE_PROJECT_DIR = $${TARGET}.xcodeproj -- cgit v1.2.3 From 8ccb9096b931ed613d47f82b43eefdd4ac779436 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 17 Oct 2013 16:20:42 +0200 Subject: iOS: Add default QT_ARCH for configure tests to our own qt_config.prf Setting QT_ARCH when empty is a workaround for a missing qconfig.pri, since it hasn't been written yet by configure. As qconfig.pri is loaded by the generic qt_config.prf, putting our workaround in our own wrapper for qt_config makes sense, as it keeps the logic close to where the original QT_ARCH is resolved. Change-Id: I49ffc21cf5dea5ca5b6254ca8084a4dcdc359a72 Reviewed-by: Oswald Buddenhagen --- mkspecs/macx-ios-clang/features/default_post.prf | 10 ---------- mkspecs/macx-ios-clang/features/qt_config.prf | 12 ++++++++++++ 2 files changed, 12 insertions(+), 10 deletions(-) create mode 100644 mkspecs/macx-ios-clang/features/qt_config.prf diff --git a/mkspecs/macx-ios-clang/features/default_post.prf b/mkspecs/macx-ios-clang/features/default_post.prf index e8dc859de6..0922a8e601 100644 --- a/mkspecs/macx-ios-clang/features/default_post.prf +++ b/mkspecs/macx-ios-clang/features/default_post.prf @@ -56,16 +56,6 @@ macx-xcode { QMAKE_MAC_XCODE_SETTINGS += ios_device_family } -isEmpty(QT_ARCH) { - # The iPhoneOS and iPhoneSimulator targets share the same toolchain, - # so when configure runs the arch tests it passes the correct sysroot, - # but we fail to pick up the architecture since we're not passing -arch - # yet. Xcode does not seem to have a way to run the shared toolchain - # in a way that will automatically do this (for example xcrun -sdk). - contains(QMAKE_MAC_SDK, iphoneos.*): QT_ARCH = arm - else: QT_ARCH = i386 # Simulator -} - # Be more specific about which architecture we're targeting equals(QT_ARCH, arm): \ actual_archs = armv7 diff --git a/mkspecs/macx-ios-clang/features/qt_config.prf b/mkspecs/macx-ios-clang/features/qt_config.prf new file mode 100644 index 0000000000..d9a13f65eb --- /dev/null +++ b/mkspecs/macx-ios-clang/features/qt_config.prf @@ -0,0 +1,12 @@ +load(qt_config) + +isEmpty(QT_ARCH) { + # The configure tests are run without QT_ARCH being resolved yet, which + # means we fail to pass -arch to the compiler, resulting in broke tests. + # As the Xcode toolchain doesn't seem to have a way to auto-detect the + # arch based on the SDK, we have to hard-code the arch for configure. + contains(QMAKE_MAC_SDK, iphoneos.*): \ + QT_ARCH = arm + else: \ # Simulator + QT_ARCH = i386 +} -- cgit v1.2.3 From 14b7400de9bbe967a417c381b099186015013d57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 17 Oct 2013 16:46:32 +0200 Subject: iOS: Don't hard-code simulator and device architectures MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Id5a370248b553b7393ec1b187bd34c0ab9f28496 Reviewed-by: Tor Arne Vestbø --- mkspecs/macx-ios-clang/features/default_post.prf | 4 ++-- mkspecs/macx-ios-clang/qmake.conf | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/mkspecs/macx-ios-clang/features/default_post.prf b/mkspecs/macx-ios-clang/features/default_post.prf index 0922a8e601..fa81ae406d 100644 --- a/mkspecs/macx-ios-clang/features/default_post.prf +++ b/mkspecs/macx-ios-clang/features/default_post.prf @@ -58,9 +58,9 @@ macx-xcode { # Be more specific about which architecture we're targeting equals(QT_ARCH, arm): \ - actual_archs = armv7 + actual_archs = $$QMAKE_IOS_DEVICE_ARCHS else: \ - actual_archs = $$QT_ARCH + actual_archs = $$QMAKE_IOS_SIMULATOR_ARCHS macx-xcode { QMAKE_XCODE_ARCHS = $$actual_archs diff --git a/mkspecs/macx-ios-clang/qmake.conf b/mkspecs/macx-ios-clang/qmake.conf index b8ef04858a..7b2e7a17e7 100644 --- a/mkspecs/macx-ios-clang/qmake.conf +++ b/mkspecs/macx-ios-clang/qmake.conf @@ -15,6 +15,9 @@ DEFINES += DARWIN_NO_CARBON QT_NO_PRINTER QT_NO_PRINTDIALOG # Universal target (iPhone and iPad) QMAKE_IOS_TARGETED_DEVICE_FAMILY = 1,2 +QMAKE_IOS_DEVICE_ARCHS = armv7 +QMAKE_IOS_SIMULATOR_ARCHS = i386 + include(../common/ios.conf) include(../common/gcc-base-mac.conf) include(../common/clang.conf) -- cgit v1.2.3 From a25e6528d3806d3b5fd87c5a1cacd6c748215db1 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Fri, 18 Oct 2013 14:51:04 +0200 Subject: Cocoa: Allow popups to grab mouse and keyboard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to the QWindow documentation this should happen regardless of the window type. (It also mimics the current behavior on Linux and Windows). Change-Id: I1b0959ad8cf19bce452fd79a13b07d0a3a3c49e9 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoawindow.h | 1 + src/plugins/platforms/cocoa/qcocoawindow.mm | 9 ++++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h index 6598bf393e..7f0f07e912 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.h +++ b/src/plugins/platforms/cocoa/qcocoawindow.h @@ -201,6 +201,7 @@ public: // for QNSView bool m_isExposed; int m_registerTouchCount; bool m_resizableTransientParent; + bool m_overrideBecomeKey; static const int NoAlertRequest; NSInteger m_alertRequest; diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 522b48a61e..845cc1202f 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -160,7 +160,9 @@ static bool isMouseEvent(NSEvent *ev) // Only tool or dialog windows should become key: if (m_cocoaPlatformWindow - && (m_cocoaPlatformWindow->window()->type() == Qt::Tool || m_cocoaPlatformWindow->window()->type() == Qt::Dialog)) + && (m_cocoaPlatformWindow->m_overrideBecomeKey || + m_cocoaPlatformWindow->window()->type() == Qt::Tool || + m_cocoaPlatformWindow->window()->type() == Qt::Dialog)) return YES; return NO; } @@ -212,6 +214,7 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw) , m_isExposed(false) , m_registerTouchCount(0) , m_resizableTransientParent(false) + , m_overrideBecomeKey(false) , m_alertRequest(NoAlertRequest) , monitor(nil) { @@ -677,6 +680,8 @@ bool QCocoaWindow::setKeyboardGrabEnabled(bool grab) if (!m_nsWindow) return false; + m_overrideBecomeKey = grab; + if (grab && ![m_nsWindow isKeyWindow]) [m_nsWindow makeKeyWindow]; else if (!grab && [m_nsWindow isKeyWindow]) @@ -689,6 +694,8 @@ bool QCocoaWindow::setMouseGrabEnabled(bool grab) if (!m_nsWindow) return false; + m_overrideBecomeKey = grab; + if (grab && ![m_nsWindow isKeyWindow]) [m_nsWindow makeKeyWindow]; else if (!grab && [m_nsWindow isKeyWindow]) -- cgit v1.2.3 From c7d34a6cd0f9936d866b26807584131927c29dc7 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 17 Oct 2013 18:52:46 +0200 Subject: more escaping of slashes in awk regexp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit apparently some awks need the regexp delimiters to be escaped even within a character list. Change-Id: I74a77022e134cafa269960c5c88a9a88589f1b95 Reviewed-by: Tor Arne Vestbø --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index afd850ab7b..fcd9f08ed1 100755 --- a/configure +++ b/configure @@ -3037,7 +3037,7 @@ function normalize(dir) { do { odir = dir - gsub(/\\/[^/]+\\/\\.\\./, "", dir) + gsub(/\\/[^\\/]+\\/\\.\\./, "", dir) } while (dir != odir); do { odir = dir -- cgit v1.2.3 From c4a51166f59416b8a5dc578079bf69097780a11b Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 18 Oct 2013 11:28:19 +0200 Subject: Fix widgets link error on iOS (missing mac gesture recognizers). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Iebea6b6e26e9aca9a64aecc9b125c48fe1cc7e43 Reviewed-by: Tor Arne Vestbø --- src/widgets/kernel/qgesturemanager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/widgets/kernel/qgesturemanager.cpp b/src/widgets/kernel/qgesturemanager.cpp index 6a0ccacdaa..18abad4b40 100644 --- a/src/widgets/kernel/qgesturemanager.cpp +++ b/src/widgets/kernel/qgesturemanager.cpp @@ -51,7 +51,7 @@ #include "qevent.h" #include "qgraphicsitem.h" -#ifdef Q_OS_MAC +#ifdef Q_OS_OSX #include "qmacgesturerecognizer_p.h" #endif #if defined(Q_WS_WIN) && !defined(QT_NO_NATIVE_GESTURES) @@ -76,7 +76,7 @@ QGestureManager::QGestureManager(QObject *parent) { qRegisterMetaType(); -#if defined(Q_OS_MAC) +#if defined(Q_OS_OSX) registerGestureRecognizer(new QMacSwipeGestureRecognizer); registerGestureRecognizer(new QMacPinchGestureRecognizer); registerGestureRecognizer(new QMacPanGestureRecognizer); -- cgit v1.2.3 From 4dab27933db18bda3d2a3272bf1f07f68aa80985 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 18 Oct 2013 17:24:24 +0300 Subject: Clear qt_tablet_target in ~QWidgetWindow. Task-number: QTBUG-34007 Change-Id: If67563e5d9c4040256b58521773736e14db6fbaf Reviewed-by: Laszlo Agocs --- src/widgets/kernel/qwidgetwindow.cpp | 6 ++++++ src/widgets/kernel/qwidgetwindow_qpa_p.h | 1 + 2 files changed, 7 insertions(+) diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index 668d5b0fc0..51a0eb7d72 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -86,6 +86,12 @@ QWidgetWindow::QWidgetWindow(QWidget *widget) connect(m_widget, &QObject::objectNameChanged, this, &QWidgetWindow::updateObjectName); } +QWidgetWindow::~QWidgetWindow() +{ + if (m_widget == qt_tablet_target) + qt_tablet_target = 0; +} + #ifndef QT_NO_ACCESSIBILITY QAccessibleInterface *QWidgetWindow::accessibleRoot() const { diff --git a/src/widgets/kernel/qwidgetwindow_qpa_p.h b/src/widgets/kernel/qwidgetwindow_qpa_p.h index 341aaba0d5..ffde44dd27 100644 --- a/src/widgets/kernel/qwidgetwindow_qpa_p.h +++ b/src/widgets/kernel/qwidgetwindow_qpa_p.h @@ -58,6 +58,7 @@ class QWidgetWindow : public QWindow Q_OBJECT public: QWidgetWindow(QWidget *widget); + ~QWidgetWindow(); QWidget *widget() const { return m_widget; } #ifndef QT_NO_ACCESSIBILITY -- cgit v1.2.3 From befe02aa6efeb351439112b27fc43e9866d6ea3d Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Fri, 18 Oct 2013 13:25:19 +0200 Subject: Fix crash in qdoc startup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit the order of initialization of static variables is undefined, and we therefore cannot (safely) initialize the array with static QStrings declared elsewhere. This was leading to crashes in MinGW gcc 4.8.0. Work around the issue by initializing the array at runtime initialization instead. Task-number: QTBUG-34172 Change-Id: I24f0e6af6685fc280d12c8ef90d40b8ebe994450 Reviewed-by: Martin Smith Reviewed-by: JÄ™drzej Nowacki --- src/tools/qdoc/main.cpp | 48 +++++++++++++++++++++++------------------------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/src/tools/qdoc/main.cpp b/src/tools/qdoc/main.cpp index dd72be7f6e..246e4d2d82 100644 --- a/src/tools/qdoc/main.cpp +++ b/src/tools/qdoc/main.cpp @@ -68,27 +68,6 @@ QT_BEGIN_NAMESPACE -/* - The default indent for code is 4. - The default value for false is 0. - The default supported file extensions are cpp, h, qdoc and qml. - The default language is c++. - The default output format is html. - The default tab size is 8. - And those are all the default values for configuration variables. - */ -static const struct { - const QString key; - const QString value; -} defaults[] = { - { CONFIG_CODEINDENT, QLatin1String("4") }, - { CONFIG_FALSEHOODS, QLatin1String("0") }, - { CONFIG_FILEEXTENSIONS, QLatin1String("*.cpp *.h *.qdoc *.qml") }, - { CONFIG_LANGUAGE, QLatin1String("Cpp") }, - { CONFIG_OUTPUTFORMATS, QLatin1String("HTML") }, - { CONFIG_TABSIZE, QLatin1String("8") }, - { QString(), QString() } -}; bool creationTimeBefore(const QFileInfo &fi1, const QFileInfo &fi2) { @@ -268,11 +247,30 @@ static void processQdocconfFile(const QString &fileName) initialize the configuration with some default values. */ Config config(QCoreApplication::translate("QDoc", "qdoc")); - int i = 0; - while (!defaults[i].key.isEmpty()) { - config.setStringList(defaults[i].key, QStringList() << defaults[i].value); - ++i; + + /* + The default indent for code is 4. + The default value for false is 0. + The default supported file extensions are cpp, h, qdoc and qml. + The default language is c++. + The default output format is html. + The default tab size is 8. + And those are all the default values for configuration variables. + */ + static QHash defaults; + if (defaults.isEmpty()) { + defaults.insert(CONFIG_CODEINDENT, QLatin1String("4")); + defaults.insert(CONFIG_FALSEHOODS, QLatin1String("0")); + defaults.insert(CONFIG_FILEEXTENSIONS, QLatin1String("*.cpp *.h *.qdoc *.qml")); + defaults.insert(CONFIG_LANGUAGE, QLatin1String("Cpp")); + defaults.insert(CONFIG_OUTPUTFORMATS, QLatin1String("HTML")); + defaults.insert(CONFIG_TABSIZE, QLatin1String("8")); } + + QHash::iterator iter; + for (iter = defaults.begin(); iter != defaults.end(); ++iter) + config.setStringList(iter.key(), QStringList() << iter.value()); + config.setStringList(CONFIG_SYNTAXHIGHLIGHTING, QStringList(highlighting ? "true" : "false")); config.setStringList(CONFIG_SHOWINTERNAL, QStringList(showInternal ? "true" : "false")); config.setStringList(CONFIG_REDIRECTDOCUMENTATIONTODEVNULL, QStringList(redirectDocumentationToDevNull ? "true" : "false")); -- cgit v1.2.3 From 229d92dc1e20cd49ef8235c063df8fa948b3fcda Mon Sep 17 00:00:00 2001 From: Martin Klapetek Date: Fri, 18 Oct 2013 15:19:19 +0200 Subject: If CUPS has no default printer, set up the first one in list Otherwise QCUPSSupport is instantiated without any printer being set up, which leads to bugs and/or crashes in other parts using QCUPSSupport. Change-Id: I1f4ddde5a28d6448d78aed856104ce8448e213c7 Reviewed-by: John Layt --- src/printsupport/kernel/qcups.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/printsupport/kernel/qcups.cpp b/src/printsupport/kernel/qcups.cpp index 643ffef192..f14d4b8dd3 100644 --- a/src/printsupport/kernel/qcups.cpp +++ b/src/printsupport/kernel/qcups.cpp @@ -144,11 +144,13 @@ QCUPSSupport::QCUPSSupport() for (int i = 0; i < prnCount; ++i) { if (printers[i].is_default) { currPrinterIndex = i; - setCurrentPrinter(i); break; } } + if (prnCount > 0) + setCurrentPrinter(currPrinterIndex); + #ifndef QT_NO_TEXTCODEC cups_lang_t *cupsLang = _cupsLangGet(0); codec = QTextCodec::codecForName(_cupsLangEncoding(cupsLang)); -- cgit v1.2.3 From fcedf4073aaa8bebf7cd5e12fab737166f1b399f Mon Sep 17 00:00:00 2001 From: Martin Klapetek Date: Fri, 18 Oct 2013 17:31:46 +0200 Subject: Set currently selected printer to QCUPSSupport in PageSetupWidget Also adds new method to allows setting a printer in QCUPSSupport by printer name. Change-Id: Iff7a88d95eab9de2c96872c45b12e708207bda16 Reviewed-by: John Layt --- src/printsupport/dialogs/qpagesetupdialog_unix.cpp | 1 + src/printsupport/kernel/qcups.cpp | 11 +++++++++++ src/printsupport/kernel/qcups_p.h | 1 + 3 files changed, 13 insertions(+) diff --git a/src/printsupport/dialogs/qpagesetupdialog_unix.cpp b/src/printsupport/dialogs/qpagesetupdialog_unix.cpp index cdb80f96a8..8809b52751 100644 --- a/src/printsupport/dialogs/qpagesetupdialog_unix.cpp +++ b/src/printsupport/dialogs/qpagesetupdialog_unix.cpp @@ -408,6 +408,7 @@ void QPageSetupWidget::selectPrinter() if (QCUPSSupport::isAvailable()) { m_cups = true; QCUPSSupport cups; + cups.setCurrentPrinter(m_printer->printerName()); const ppd_option_t* pageSizes = cups.pageSizes(); const int numChoices = pageSizes ? pageSizes->num_choices : 0; diff --git a/src/printsupport/kernel/qcups.cpp b/src/printsupport/kernel/qcups.cpp index f14d4b8dd3..e237d44dcd 100644 --- a/src/printsupport/kernel/qcups.cpp +++ b/src/printsupport/kernel/qcups.cpp @@ -215,6 +215,17 @@ const ppd_file_t* QCUPSSupport::setCurrentPrinter(int index) return currPPD; } +const ppd_file_t* QCUPSSupport::setCurrentPrinter(const QString &printerName) +{ + Q_FOREACH (const QCUPSSupport::Printer &printer, QCUPSSupport::availableUnixPrinters()) { + if (printer.name == printerName) { + return setCurrentPrinter(printer.cupsPrinterIndex); + } + } + + return 0; +} + int QCUPSSupport::currentPrinterIndex() const { return currPrinterIndex; diff --git a/src/printsupport/kernel/qcups_p.h b/src/printsupport/kernel/qcups_p.h index 726bc7eba6..95ca323c22 100644 --- a/src/printsupport/kernel/qcups_p.h +++ b/src/printsupport/kernel/qcups_p.h @@ -149,6 +149,7 @@ public: const cups_dest_t* availablePrinters() const; int currentPrinterIndex() const; const ppd_file_t* setCurrentPrinter(int index); + const ppd_file_t* setCurrentPrinter(const QString &printerName); const ppd_file_t* currentPPD() const; const ppd_option_t* ppdOption(const char *key) const; -- cgit v1.2.3 From 7ded7c8f9e6679f1352e05e1e4a0af48cda0507a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 18 Oct 2013 16:42:21 +0200 Subject: Explicitly mark subdirs as host_builds in SUBDIRS template MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allows post-processing code to exclude recursing into host_build subdirs. The alternative would be to have the SUBDIRS logic pre-parse the subdir project to check if it's a host_build, but that might have a performance impact, so it's better to leave the information explicit in the subdir project file. Change-Id: I1a6f7d94c49faf5f5106c83ef21f6b85b531c90b Reviewed-by: Tor Arne Vestbø --- src/src.pro | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/src.pro b/src/src.pro index 377e8cb650..b7887a6108 100644 --- a/src/src.pro +++ b/src/src.pro @@ -2,36 +2,44 @@ TEMPLATE = subdirs src_tools_bootstrap.subdir = tools/bootstrap src_tools_bootstrap.target = sub-bootstrap +src_tools_bootstrap.CONFIG = host_build src_tools_moc.subdir = tools/moc src_tools_moc.target = sub-moc src_tools_moc.depends = src_tools_bootstrap +src_tools_moc.CONFIG = host_build src_tools_rcc.subdir = tools/rcc src_tools_rcc.target = sub-rcc src_tools_rcc.depends = src_tools_bootstrap +src_tools_rcc.CONFIG = host_build src_tools_uic.subdir = tools/uic src_tools_uic.target = sub-uic +src_tools_uic.CONFIG = host_build force_bootstrap: src_tools_uic.depends = src_tools_bootstrap else: src_tools_uic.depends = src_corelib src_tools_qdoc.subdir = tools/qdoc src_tools_qdoc.target = sub-qdoc +src_tools_qdoc.CONFIG = host_build force_bootstrap: src_tools_qdoc.depends = src_tools_bootstrap else: src_tools_qdoc.depends = src_corelib src_xml src_tools_bootstrap_dbus.subdir = tools/bootstrap-dbus src_tools_bootstrap_dbus.target = sub-bootstrap_dbus src_tools_bootstrap_dbus.depends = src_tools_bootstrap +src_tools_bootstrap_dbus.CONFIG = host_build src_tools_qdbusxml2cpp.subdir = tools/qdbusxml2cpp src_tools_qdbusxml2cpp.target = sub-qdbusxml2cpp +src_tools_qdbusxml2cpp.CONFIG = host_build force_bootstrap: src_tools_qdbusxml2cpp.depends = src_tools_bootstrap_dbus else: src_tools_qdbusxml2cpp.depends = src_dbus src_tools_qdbuscpp2xml.subdir = tools/qdbuscpp2xml src_tools_qdbuscpp2xml.target = sub-qdbuscpp2xml +src_tools_qdbuscpp2xml.CONFIG = host_build force_bootstrap: src_tools_qdbuscpp2xml.depends = src_tools_bootstrap_dbus else: src_tools_qdbuscpp2xml.depends = src_dbus -- cgit v1.2.3 From e06acfbda2a1d45f349630cfc412a159c059ef39 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Fri, 18 Oct 2013 13:43:20 +0200 Subject: Android: Remove support for QMAKE_SUPPORTED_ORIENTATIONS This was created for the iOS port and intended to be cross-platform, but since then they got cold feet and never added the support. It makes no sense to only support this on Android. We need to remove it again and hold off until we can find a proper solution. Editing the AndroidManifest.xml is the non-cross-platform solution for this. Task-number: QTBUG-34166 Change-Id: I51d53b82a3412a9016de01612dd8df9ae12c6633 Reviewed-by: BogDan Vatra --- mkspecs/features/android/android_deployment_settings.prf | 3 --- 1 file changed, 3 deletions(-) diff --git a/mkspecs/features/android/android_deployment_settings.prf b/mkspecs/features/android/android_deployment_settings.prf index 9ac826e860..a903ed025d 100644 --- a/mkspecs/features/android/android_deployment_settings.prf +++ b/mkspecs/features/android/android_deployment_settings.prf @@ -62,9 +62,6 @@ contains(TEMPLATE, ".*app"):!build_pass:!android-no-sdk { !isEmpty(ANDROID_EXTRA_LIBS): \ FILE_CONTENT += " \"android-extra-libs\": $$emitString($$join(ANDROID_EXTRA_LIBS, ","))," - !isEmpty(QMAKE_SUPPORTED_ORIENTATIONS): \ - FILE_CONTENT += " \"supported-orientations\": $$emitString($$join(QMAKE_SUPPORTED_ORIENTATIONS, ","))," - FILE_CONTENT += " \"application-binary\": $$emitString($$absolute_path($$DESTDIR, $$OUT_PWD)/$$TARGET)" FILE_CONTENT += "}" -- cgit v1.2.3 From a652bab6a7ebf78b029fea95c2801deb6f4f524a Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Wed, 16 Oct 2013 16:26:40 +0200 Subject: Link from QLoggingCategory documentation to QTracer/QTraceGuard Change-Id: I331966f6137a31f089425a639afe8f9f4088c0b6 Reviewed-by: Jerome Pasion Reviewed-by: hjk --- src/corelib/io/qloggingcategory.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/corelib/io/qloggingcategory.cpp b/src/corelib/io/qloggingcategory.cpp index e3151b61cc..d472682ace 100644 --- a/src/corelib/io/qloggingcategory.cpp +++ b/src/corelib/io/qloggingcategory.cpp @@ -401,7 +401,7 @@ void QLoggingCategory::setFilterRules(const QString &rules) The macro expands to code that checks whether \l QLoggingCategory::isTraceEnabled() evaluates to \c true. - If so, the stream arguments are processed and sent to the tracers + If so, the stream arguments are processed and sent to the \l QTracer objects registered with the category. \note Arguments are not processed if trace output for the category is not @@ -411,7 +411,7 @@ void QLoggingCategory::setFilterRules(const QString &rules) \snippet qtracer/ftracer.cpp 6 - \sa qCTraceGuard() + \sa qCTraceGuard() QTraceGuard */ /*! @@ -423,11 +423,12 @@ void QLoggingCategory::setFilterRules(const QString &rules) storage. The guard constructor checks whether \l QLoggingCategory::isTraceEnabled() evaluates to \c true. If so, the stream arguments are processed and the \c{start()} - functions of the tracers registered with the \a category are called. + functions of the \l QTracer objects registered with the \a category are + called. The guard destructor also checks whether the category is enabled for tracing and if so, the \c{end()} - functions of the tracers registered with the \a category are called. + functions of the \l QTracer objects registered with the \a category are called. \note Arguments are always processed, even if trace output for the category is disabled. They will, however, in that case not be passed @@ -437,7 +438,7 @@ void QLoggingCategory::setFilterRules(const QString &rules) \snippet qtracer/ftracer.cpp 4 - \sa qCTrace() + \sa qCTrace() QTracer */ /*! -- cgit v1.2.3 From c057e23b02637c1fad270a0cfe2248b50ee418f6 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Wed, 9 Oct 2013 13:47:52 +0200 Subject: When creating QVariant(QPolygonF()) this should be a null variant MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The handling of the null QPolygonF case was not correct as it would always be seen as valid. This ensures it is treated in the same way as QPolygon when it is in fact null. [ChangeLog][QtGui][QPolygonF] When a QVariant holds a QPolygonF() then it will be correctly seen as a null QVariant. Change-Id: Icae34f513c3a8e1dd3f50cb64a3d13ae7c636cc4 Reviewed-by: Stephen Kelly Reviewed-by: JÄ™drzej Nowacki --- src/gui/kernel/qguivariant.cpp | 3 ++- tests/auto/gui/kernel/qguivariant/test/tst_qguivariant.cpp | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gui/kernel/qguivariant.cpp b/src/gui/kernel/qguivariant.cpp index 2842211e1d..b4e936f818 100644 --- a/src/gui/kernel/qguivariant.cpp +++ b/src/gui/kernel/qguivariant.cpp @@ -115,7 +115,7 @@ static void clear(QVariant::Private *d) QMetaTypeSwitcher::switcher(destructor, d->type, 0); } -// This class is a hack that customizes access to QPolygon +// This class is a hack that customizes access to QPolygon and QPolygonF template class QGuiVariantIsNull : public QVariantIsNull { typedef QVariantIsNull Base; @@ -126,6 +126,7 @@ public: template bool delegate(const T *p) { return Base::delegate(p); } bool delegate(const QPolygon*) { return v_cast(Base::m_d)->isEmpty(); } + bool delegate(const QPolygonF*) { return v_cast(Base::m_d)->isEmpty(); } bool delegate(const void *p) { return Base::delegate(p); } }; static bool isNull(const QVariant::Private *d) diff --git a/tests/auto/gui/kernel/qguivariant/test/tst_qguivariant.cpp b/tests/auto/gui/kernel/qguivariant/test/tst_qguivariant.cpp index 8a68f40f3f..4b2cce63e5 100644 --- a/tests/auto/gui/kernel/qguivariant/test/tst_qguivariant.cpp +++ b/tests/auto/gui/kernel/qguivariant/test/tst_qguivariant.cpp @@ -526,6 +526,7 @@ void tst_QGuiVariant::writeToReadFromDataStream_data() QTest::newRow( "pointarray_valid" ) << QVariant::fromValue( QPolygon( QRect( 10, 10, 20, 20 ) ) ) << false; QTest::newRow( "region_invalid" ) << QVariant::fromValue( QRegion() ) << true; QTest::newRow( "region_valid" ) << QVariant::fromValue( QRegion( 10, 10, 20, 20 ) ) << false; + QTest::newRow("polygonf_invalid") << QVariant::fromValue(QPolygonF()) << true; QTest::newRow("polygonf_valid") << QVariant::fromValue(QPolygonF(QRectF(10, 10, 20, 20))) << false; } -- cgit v1.2.3 From 21ce4fd240a876ffcb6ab4c2c4ccdd4ff28eef87 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 18 Oct 2013 13:26:16 +0200 Subject: make it possible to explicitly suppress the qml import scan if the user knows that no additional imports need to be linked, this can be used to optimize the build time. as it happens, it can also be used to fix the build of the qml tools themselves ... Change-Id: Id77aea1f20cabdc2e831540c61d8a4b8e85c040b Reviewed-by: Joerg Bornemann --- mkspecs/features/qt.prf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mkspecs/features/qt.prf b/mkspecs/features/qt.prf index a4f082e056..59147faffc 100644 --- a/mkspecs/features/qt.prf +++ b/mkspecs/features/qt.prf @@ -74,7 +74,8 @@ wince*:static:gui { } # static builds: link qml import plugins into the app. -if(contains(QT, qml)|contains(QT_PRIVATE, qml)):contains(QT_CONFIG, static):contains(TEMPLATE, .*app):!host_build { +if(contains(QT, qml)|contains(QT_PRIVATE, qml)): \ + contains(QT_CONFIG, static):contains(TEMPLATE, .*app):!host_build:!no_import_scan { # run qmlimportscanner qtPrepareTool(QMLIMPORTSCANNER, qmlimportscanner) exists($$QMLIMPORTSCANNER) { -- cgit v1.2.3 From 27b10259bcca78f5e3e757b3c97695a544d59379 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 8 Oct 2013 20:16:01 +0200 Subject: don't bother defining QT_NO_DIRECTWRITE here the relevant code moved to the windows platform plugin. Change-Id: I06f2efd1190ee7d1da1f48172ae879e5c06a945f Reviewed-by: Joerg Bornemann Reviewed-by: Friedemann Kleint --- src/widgets/widgets.pro | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/widgets/widgets.pro b/src/widgets/widgets.pro index 3771b97a31..e3222b49e8 100644 --- a/src/widgets/widgets.pro +++ b/src/widgets/widgets.pro @@ -44,7 +44,3 @@ QMAKE_DYNAMIC_LIST_FILE = $$PWD/QtWidgets.dynlist testcocoon { load(testcocoon) } - -win32:!contains(QT_CONFIG, directwrite) { - DEFINES += QT_NO_DIRECTWRITE -} -- cgit v1.2.3 From bae926e66d74bbd5ab00d1d0bcb92671ab812e8e Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 8 Oct 2013 14:51:00 +0200 Subject: exclude gui-needing tests from -no-gui build Change-Id: I91f7211efe44cbb41aa3058f85869a6babf121f3 Reviewed-by: Stephen Kelly --- tests/auto/auto.pro | 1 + tests/auto/corelib/io/io.pro | 4 ++++ tests/auto/corelib/itemmodels/itemmodels.pro | 4 +++- tests/auto/corelib/kernel/kernel.pro | 3 +++ 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index e16f229c4e..3ff78a955f 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -23,6 +23,7 @@ wince*: SUBDIRS -= printsupport cross_compile: SUBDIRS -= tools !qtHaveModule(opengl): SUBDIRS -= opengl !unix|embedded|!qtHaveModule(dbus): SUBDIRS -= dbus +!qtHaveModule(gui): SUBDIRS -= gui cmake !qtHaveModule(widgets): SUBDIRS -= widgets !qtHaveModule(printsupport): SUBDIRS -= printsupport !qtHaveModule(concurrent): SUBDIRS -= concurrent diff --git a/tests/auto/corelib/io/io.pro b/tests/auto/corelib/io/io.pro index 41d7e7e08b..ab66323d3b 100644 --- a/tests/auto/corelib/io/io.pro +++ b/tests/auto/corelib/io/io.pro @@ -38,6 +38,10 @@ SUBDIRS=\ qwinoverlappedionotifier } +!qtHaveModule(gui): SUBDIRS -= \ + qdatastream \ + qsettings + !qtHaveModule(network): SUBDIRS -= \ qfile \ qiodevice \ diff --git a/tests/auto/corelib/itemmodels/itemmodels.pro b/tests/auto/corelib/itemmodels/itemmodels.pro index 3f726692ff..7e0e3a0944 100644 --- a/tests/auto/corelib/itemmodels/itemmodels.pro +++ b/tests/auto/corelib/itemmodels/itemmodels.pro @@ -1,10 +1,12 @@ TEMPLATE=subdirs SUBDIRS = qabstractitemmodel \ + qstringlistmodel \ + +qtHaveModule(gui): SUBDIRS += \ qabstractproxymodel \ qidentityproxymodel \ qitemselectionmodel \ - qstringlistmodel \ qtHaveModule(widgets): SUBDIRS += \ qitemmodel \ diff --git a/tests/auto/corelib/kernel/kernel.pro b/tests/auto/corelib/kernel/kernel.pro index a283f5343d..fe3e4b7e0a 100644 --- a/tests/auto/corelib/kernel/kernel.pro +++ b/tests/auto/corelib/kernel/kernel.pro @@ -21,6 +21,9 @@ SUBDIRS=\ qvariant \ qwineventnotifier +!qtHaveModule(gui): SUBDIRS -= \ + qmimedata + !qtHaveModule(network): SUBDIRS -= \ qeventloop \ qobject \ -- cgit v1.2.3 From ab17a3c3c40d578397fd9d2d03eda8e13976fcfc Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 18 Oct 2013 13:20:41 +0200 Subject: remove broken validation of QMLIMPORTSCANNER the variable may contain a complex command, so an exists() check is doomed to failure if the tool is built dynamically. also, the check is not really necessary: it failing indicates a bug in the qt build system, and we don't really need to complicate the code to deal with such corner cases. Change-Id: I2e6087dcc6dd4a4f70bdf739550276f364c880dd Reviewed-by: Joerg Bornemann --- mkspecs/features/qt.prf | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/mkspecs/features/qt.prf b/mkspecs/features/qt.prf index 59147faffc..04375d4ce1 100644 --- a/mkspecs/features/qt.prf +++ b/mkspecs/features/qt.prf @@ -78,21 +78,16 @@ if(contains(QT, qml)|contains(QT_PRIVATE, qml)): \ contains(QT_CONFIG, static):contains(TEMPLATE, .*app):!host_build:!no_import_scan { # run qmlimportscanner qtPrepareTool(QMLIMPORTSCANNER, qmlimportscanner) - exists($$QMLIMPORTSCANNER) { - for (MODULE, QT_MODULES) { - PATH = $$eval(QT.$${MODULE}.qml) - !isEmpty(PATH): QMLPATHS += $$PATH - } - QMLPATHS = $$unique(QMLPATHS) - for (QMLPATH, QMLPATHS): \ - IMPORTPATHS += -importPath $$QMLPATH - - #message(run $$QMLIMPORTSCANNER $$_PRO_FILE_PWD_ $$IMPORTPATHS) - JSON = $$system($$QMLIMPORTSCANNER $$_PRO_FILE_PWD_ $$IMPORTPATHS) - } else { - error("qmlimportscanner is missing. Rebuild qtdeclarative/tools/qmlimportscanner.") - JSON = [] + for (MODULE, QT_MODULES) { + PATH = $$eval(QT.$${MODULE}.qml) + !isEmpty(PATH): QMLPATHS += $$PATH } + QMLPATHS = $$unique(QMLPATHS) + for (QMLPATH, QMLPATHS): \ + IMPORTPATHS += -importPath $$QMLPATH + + #message(run $$QMLIMPORTSCANNER $$_PRO_FILE_PWD_ $$IMPORTPATHS) + JSON = $$system($$QMLIMPORTSCANNER $$_PRO_FILE_PWD_ $$IMPORTPATHS) parseJson(JSON, IMPORTS)| error("Failed to parse qmlimportscanner output.") -- cgit v1.2.3 From 22c2d13406394077792c106ce1b60b3203aaf392 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Mon, 14 Oct 2013 15:59:45 +0200 Subject: Make it possible to clear glyph caches from the font engine. Change-Id: Iea62bc1727269ed3893d8b4dbcefa583f1b85d7f Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/text/qfontengine.cpp | 10 ++++++++++ src/gui/text/qfontengine_p.h | 1 + 2 files changed, 11 insertions(+) diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index b3889a02a4..303c85ce75 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -891,6 +891,16 @@ QByteArray QFontEngine::getSfntTable(uint tag) const return table; } +void QFontEngine::clearGlyphCache(const void *key) +{ + for (QLinkedList::iterator it = m_glyphCaches.begin(), end = m_glyphCaches.end(); it != end; ) { + if (it->context == key) + it = m_glyphCaches.erase(it); + else + ++it; + } +} + void QFontEngine::setGlyphCache(const void *key, QFontEngineGlyphCache *data) { Q_ASSERT(data); diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h index d3faef93bb..c181d61d73 100644 --- a/src/gui/text/qfontengine_p.h +++ b/src/gui/text/qfontengine_p.h @@ -256,6 +256,7 @@ public: virtual int getPointInOutline(glyph_t glyph, int flags, quint32 point, QFixed *xpos, QFixed *ypos, quint32 *nPoints); + void clearGlyphCache(const void *key); void setGlyphCache(const void *key, QFontEngineGlyphCache *data); QFontEngineGlyphCache *glyphCache(const void *key, QFontEngineGlyphCache::Type type, const QTransform &transform) const; -- cgit v1.2.3 From deb925b1b6dccec5c36a3d0a302fcb5ec58b040d Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 14 Oct 2013 18:13:14 -0700 Subject: Change an addition into a subtraction This potentially resolves the long-standing warning from GCC: assuming signed overflow does not occur when assuming that (X + c) < X is always false GCC prints the warning to warn people that you can't check for overflow with signed integers by doing that (signed integers don't overflow in the standard). If we change this to X < X - c, there's no overflow. Task-number: QTBUG-33314 Change-Id: I5b166610a39559ec7b03c4c31ee5999efefa0c06 Reviewed-by: Olivier Goffart --- src/corelib/tools/qlist.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h index b795bbc86e..333ce72849 100644 --- a/src/corelib/tools/qlist.h +++ b/src/corelib/tools/qlist.h @@ -639,7 +639,7 @@ inline void QList::move(int from, int to) template Q_OUTOFLINE_TEMPLATE QList QList::mid(int pos, int alength) const { - if (alength < 0 || pos + alength > size()) + if (alength < 0 || pos > size() - alength) alength = size() - pos; if (pos == 0 && alength == size()) return *this; -- cgit v1.2.3 From 24d926cb8fb421b751b5be97fd214469e4c429c2 Mon Sep 17 00:00:00 2001 From: Sergio Martins Date: Sat, 19 Oct 2013 22:09:17 +0100 Subject: Initialize variable to fix build [-Werror=uninitialized]. The complaining compiler is: gcc version 4.6.3 (crosstool-NG hg+default-ddc327ebaef2) Change-Id: Iae488a89d75492e76a39a326b2db36548f8894d0 Reviewed-by: Thiago Macieira --- src/corelib/io/qurlrecode.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/corelib/io/qurlrecode.cpp b/src/corelib/io/qurlrecode.cpp index ba1a77744c..80fc0319fe 100644 --- a/src/corelib/io/qurlrecode.cpp +++ b/src/corelib/io/qurlrecode.cpp @@ -410,10 +410,9 @@ static int recode(QString &result, const ushort *begin, const ushort *end, QUrl: const ushort *input = begin; ushort *output = 0; + EncodingAction action = EncodeCharacter; for ( ; input != end; ++input) { ushort c; - EncodingAction action; - // try a run where no change is necessary for ( ; input != end; ++input) { c = *input; -- cgit v1.2.3 From 19b3e6489dd2f795e0bbacd5d0abe74b8ef8021c Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Mon, 14 Oct 2013 20:41:07 +0200 Subject: Android: Accessibilty: Handle text better MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Try harder to actually return text, before TalkBack would not read the contents of line edits and other text widgets. Change-Id: Ibb9bb8ac4a2728674f6f5ccf29eda5ed66a81a34 Reviewed-by: Jan Arve Sæther --- .../platforms/android/src/androidjniaccessibility.cpp | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/android/src/androidjniaccessibility.cpp b/src/plugins/platforms/android/src/androidjniaccessibility.cpp index 07f3371e72..a27d9f5aed 100644 --- a/src/plugins/platforms/android/src/androidjniaccessibility.cpp +++ b/src/plugins/platforms/android/src/androidjniaccessibility.cpp @@ -164,7 +164,7 @@ if (!clazz) { \ //__android_log_print(ANDROID_LOG_FATAL, m_qtTag, m_methodErrorMsg, METHOD_NAME, METHOD_SIGNATURE); -#define CALL_METHOD(OBJECT, METHOD_NAME, METHOD_SIGNATURE, VALUE) \ +#define CALL_METHOD(OBJECT, METHOD_NAME, METHOD_SIGNATURE, ...) \ { \ jclass clazz = env->GetObjectClass(OBJECT); \ jmethodID method = env->GetMethodID(clazz, METHOD_NAME, METHOD_SIGNATURE); \ @@ -172,7 +172,7 @@ if (!clazz) { \ __android_log_print(ANDROID_LOG_WARN, m_qtTag, m_methodErrorMsg, METHOD_NAME, METHOD_SIGNATURE); \ return; \ } \ - env->CallVoidMethod(OBJECT, method, VALUE); \ + env->CallVoidMethod(OBJECT, method, __VA_ARGS__); \ } @@ -201,9 +201,21 @@ if (!clazz) { \ } QAccessible::State state = iface->state(); - QString desc = iface->text(QAccessible::Name); + // try to fill in the text property, this is what the screen reader reads + QString desc = iface->text(QAccessible::Value); + if (desc.isEmpty()) + desc = iface->text(QAccessible::Name); if (desc.isEmpty()) desc = iface->text(QAccessible::Description); + if (QAccessibleTextInterface *textIface = iface->textInterface()) { + if (textIface->selectionCount() > 0) { + int startSelection; + int endSelection; + textIface->selection(0, &startSelection, &endSelection); + CALL_METHOD(node, "setTextSelection", "(II)V", startSelection, endSelection) + } + } + if ((iface->role() != QAccessible::NoRole) && (iface->role() != QAccessible::Client) && (iface->role() != QAccessible::Pane)) { -- cgit v1.2.3 From 32ca64706725aee0fbb747a60d1083f9b4a05028 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simo=20F=C3=A4lt?= Date: Fri, 18 Oct 2013 12:43:27 +0300 Subject: Enabling CI usage for runtests_androiddeployqt.pl - Fixed issues when having multiple devices connected at the same time. - Fixed hard coded paths - Removed not existing function call, which caused test run to exit too early. - Added possibility to add and connect to device, configured as env variable. Task-number: QTQAINFRA-641 Change-Id: I8c1e003ce4ffbc9fdd9572dc55eef8fe92330cba Reviewed-by: Eskil Abrahamsen Blomfeldt --- tests/auto/android/runtests_androiddeployqt.pl | 29 ++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/tests/auto/android/runtests_androiddeployqt.pl b/tests/auto/android/runtests_androiddeployqt.pl index 7940653176..d3c9a7bc11 100755 --- a/tests/auto/android/runtests_androiddeployqt.pl +++ b/tests/auto/android/runtests_androiddeployqt.pl @@ -60,8 +60,11 @@ my $man = 0; my $help = 0; my $make_clean = 0; my $time_out=400; +my $android_toolchain_version = "4.8"; +my $host_arch = "linux-x86"; my $android_sdk_dir = "$ENV{'ANDROID_SDK_ROOT'}"; my $android_ndk_dir = "$ENV{'ANDROID_NDK_ROOT'}"; +my $android_to_connect = "$ENV{'ANDROID_DEVICE'}"; my $ant_tool = `which ant`; chomp $ant_tool; my $strip_tool=""; @@ -74,6 +77,8 @@ GetOptions('h|help' => \$help , 'j|jobs=i' => \$jobs , 'sdk=s' => \$android_sdk_dir , 'ndk=s' => \$android_ndk_dir + , 'toolchain=s' => \$android_toolchain_version + , 'host=s' => \$host_arch , 'ant=s' => \$ant_tool , 'strip=s' => \$strip_tool , 'readelf=s' => \$readelf_tool @@ -83,14 +88,29 @@ pod2usage(1) if $help; pod2usage(-verbose => 2) if $man; my $adb_tool="$android_sdk_dir/platform-tools/adb"; + +# For CI. Nodes are connecting to test devices over IP, which is stored to env variable +if ($android_to_connect ne ""){ + print " Found device to be connected from env: $android_to_connect \n"; + system("$adb_tool disconnect $android_to_connect"); + system("$adb_tool connect $android_to_connect"); + sleep(2);# let it connect + system("$adb_tool -s $android_to_connect reboot &");# adb bug, it blocks forever + sleep(15); # wait for the device to come up again + system("$adb_tool disconnect $android_to_connect");# cleans up the left adb reboot process + system("$adb_tool connect $android_to_connect"); + $device_serial =$android_to_connect; +} + + system("$adb_tool devices") == 0 or die "No device found, please plug/start at least one device/emulator\n"; # make sure we have at least on device attached -$device_serial = "-s $device_serial" if ($device_serial); $deployqt_device_serial = "--device $device_serial" if ($device_serial); +$device_serial = "-s $device_serial" if ($device_serial); $testsubset="/$testsubset" if ($testsubset); -$strip_tool="$android_ndk_dir/toolchains/arm-linux-androideabi-4.7/prebuilt/linux-x86/bin/arm-linux-androideabi-strip" unless($strip_tool); -$readelf_tool="$android_ndk_dir/toolchains/arm-linux-androideabi-4.7/prebuilt/linux-x86/bin/arm-linux-androideabi-readelf" unless($readelf_tool); +$strip_tool="$android_ndk_dir/toolchains/arm-linux-androideabi-$android_toolchain_version/prebuilt/$host_arch/bin/arm-linux-androideabi-strip" unless($strip_tool); +$readelf_tool="$android_ndk_dir/toolchains/arm-linux-androideabi-$android_toolchain_version/prebuilt/$host_arch/bin/arm-linux-androideabi-readelf" unless($readelf_tool); $readelf_tool="$readelf_tool -d -w "; sub dir @@ -174,7 +194,8 @@ sub startTest #wait to stop unless(waitForProcess($packageName,0,$time_out,5)) { - killProcess($packageName); + #killProcess($packageName); + print "Someone should kill $packageName\n"; return 1; } system("$adb_tool $device_serial pull /data/data/$packageName/output.xml $output_dir/$output_file"); -- cgit v1.2.3 From da7e534df254b4b03c289d4286f887cd98059782 Mon Sep 17 00:00:00 2001 From: Sean Harmer Date: Sun, 20 Oct 2013 15:34:37 +0100 Subject: Use QByteArrayLiteral throughout in QOpenGLVertexArrayObject Change-Id: Ia362ead0ffdc077bd0db5d980c80464838c934ea Reviewed-by: Giuseppe D'Angelo --- src/gui/opengl/qopenglvertexarrayobject.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/gui/opengl/qopenglvertexarrayobject.cpp b/src/gui/opengl/qopenglvertexarrayobject.cpp index 1f039a8ca9..ee8abde77b 100644 --- a/src/gui/opengl/qopenglvertexarrayobject.cpp +++ b/src/gui/opengl/qopenglvertexarrayobject.cpp @@ -63,14 +63,14 @@ public: DeleteVertexArrays = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glDeleteVertexArraysAPPLE"))); BindVertexArray = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glBindVertexArrayAPPLE"))); } else { - GenVertexArrays = reinterpret_cast(context->getProcAddress("glGenVertexArrays")); - DeleteVertexArrays = reinterpret_cast(context->getProcAddress("glDeleteVertexArrays")); - BindVertexArray = reinterpret_cast(context->getProcAddress("glBindVertexArray")); + GenVertexArrays = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glGenVertexArrays"))); + DeleteVertexArrays = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glDeleteVertexArrays"))); + BindVertexArray = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glBindVertexArray"))); } #else - GenVertexArrays = reinterpret_cast(context->getProcAddress("glGenVertexArraysOES")); - DeleteVertexArrays = reinterpret_cast(context->getProcAddress("glDeleteVertexArraysOES")); - BindVertexArray = reinterpret_cast(context->getProcAddress("glBindVertexArrayOES")); + GenVertexArrays = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glGenVertexArraysOES"))); + DeleteVertexArrays = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glDeleteVertexArraysOES"))); + BindVertexArray = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glBindVertexArrayOES"))); #endif } @@ -169,7 +169,7 @@ bool QOpenGLVertexArrayObjectPrivate::create() QObject::connect(context, SIGNAL(aboutToBeDestroyed()), q, SLOT(_q_contextAboutToBeDestroyed())); #if defined(QT_OPENGL_ES_2) - if (ctx->hasExtension("GL_OES_vertex_array_object")) { + if (ctx->hasExtension(QByteArrayLiteral("GL_OES_vertex_array_object"))) { vaoFuncs = new QVertexArrayObjectHelper(ctx); vaoFuncs->glGenVertexArrays(1, &vao); } @@ -187,7 +187,7 @@ bool QOpenGLVertexArrayObjectPrivate::create() vaoFuncsType = Core_3_0; vaoFuncs.core_3_0->initializeOpenGLFunctions(); vaoFuncs.core_3_0->glGenVertexArrays(1, &vao); - } else if (ctx->hasExtension("GL_ARB_vertex_array_object")) { + } else if (ctx->hasExtension(QByteArrayLiteral("GL_ARB_vertex_array_object"))) { vaoFuncs.helper = new QVertexArrayObjectHelper(ctx); vaoFuncsType = ARB; vaoFuncs.helper->glGenVertexArrays(1, &vao); -- cgit v1.2.3 From a9d5627e6a7b82188e20064d2e397b00cff8f318 Mon Sep 17 00:00:00 2001 From: Sze Howe Koh Date: Wed, 16 Oct 2013 23:37:28 +0800 Subject: Doc: Update, and reduce duplication of, QThread-related info Added/Changed: - Move content from the Thread Basics overview to the QThread class ref - Rephrase bits for clarity - Use more links Removed: - (threads-basics.qdoc) Warning against moveToThread(this): This usage came about when people tried to add slots to a QThread subclass. This patch adds a warning against the root cause. - (threads-basics.qdoc) Note on sleep() et al.: They were made public in Qt 5.0. - (threads-basics.qdoc) The strategy for managing member variables: Sounds error-prone. Pushing results through signals is safer. - (qthread.cpp) The note about GUI classes: Irrelevant to QThread, and it's already mentioned elsewhere. Change-Id: I6bc53cc22b929523f9976d2b920f94c02bd7273e Reviewed-by: Geir Vattekar Reviewed-by: Olivier Goffart --- src/corelib/doc/src/threads-basics.qdoc | 25 ------------------------- src/corelib/thread/qthread.cpp | 29 +++++++++++++++-------------- 2 files changed, 15 insertions(+), 39 deletions(-) diff --git a/src/corelib/doc/src/threads-basics.qdoc b/src/corelib/doc/src/threads-basics.qdoc index e511c10423..4f381421b4 100644 --- a/src/corelib/doc/src/threads-basics.qdoc +++ b/src/corelib/doc/src/threads-basics.qdoc @@ -199,31 +199,6 @@ still important. On Linux, Valgrind and Helgrind can help detect threading errors. - The anatomy of QThread is quite interesting: - - \list - \li QThread does not live in the new thread where \l{QThread::}{run()} is - executed. It lives in the old thread. - \li Most QThread methods are the thread's control interface and are meant to - be called from the old thread. Do not move this interface to the newly - created thread using \l{QObject::}{moveToThread()}; i.e., calling - \l{QObject::moveToThread()}{moveToThread(this)} is regarded as bad - practice. - \li \l{QThread::}{exec()} and the static methods - \l{QThread::}{usleep()}, \l{QThread::}{msleep()}, - \l{QThread::}{sleep()} are meant to be called from the newly created - thread. - \li Additional members defined in the QThread subclass are - accessible by both threads. The developer is responsible for - coordinating access. A typical strategy is to set the members before - \l{QThread::}{start()} is called. Once the worker thread is running, - the main thread should not touch the additional members anymore. After - the worker has terminated, the main thread can access the additional - members again. This is a convenient strategy for passing parameters to a - thread before it is started as well as for collecting the result once it - has terminated. - \endlist - \section2 Protecting the Integrity of Data When writing a multithread application, extra care must be taken to avoid diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp index 7667aff0b2..50ccca9eda 100644 --- a/src/corelib/thread/qthread.cpp +++ b/src/corelib/thread/qthread.cpp @@ -204,20 +204,20 @@ QThreadPrivate::~QThreadPrivate() There will not be any event loop running in the thread unless you call exec(). - It is important to remember that a QThread object usually lives - in the thread where it was created, not in the thread that it - manages. This oft-overlooked detail means that a QThread's slots - will be executed in the context of its home thread, not in the - context of the thread it is managing. For this reason, - implementing new slots in a QThread subclass is error-prone and - discouraged. + It is important to remember that a QThread instance \l{QObject#Thread + Affinity}{lives in} the old thread that instantiated it, not in the + new thread that calls run(). This means that all of QThread's queued + slots will execute in the old thread. Thus, a developer who wishes to + invoke slots in the new thread must use the worker-object approach; new + slots should not be implemented directly into a subclassed QThread. - \note If you interact with an object, using any technique other - than queued signal/slot connections (e.g. direct function calls), - then the usual multithreading precautions need to be taken. + When subclassing QThread, keep in mind that the constructor executes in + the old thread while run() executes in the new thread. If a member + variable is accessed from both functions, then the variable is accessed + from two different threads. Check that it is safe to do so. - \note It is not possible to change the thread affinity of GUI - objects; they must remain in the main thread. + \note Care must be taken when interacting with objects across different + threads. See \l{Synchronizing Threads} for details. \section1 Managing threads @@ -262,7 +262,7 @@ QThreadPrivate::~QThreadPrivate() \l{Mandelbrot Example}, as that is the name of the QThread subclass). Note that this is currently not available with release builds on Windows. - \sa {Thread Support in Qt}, QThreadStorage, QMutex, QSemaphore, QWaitCondition, + \sa {Thread Support in Qt}, QThreadStorage, {Synchronizing Threads} {Mandelbrot Example}, {Semaphores Example}, {Wait Conditions Example} */ @@ -489,7 +489,8 @@ uint QThread::stackSize() const that was passed to exit(). The value returned is 0 if exit() is called via quit(). - It is necessary to call this function to start event handling. + This function is meant to be called from within run(). It is necessary to + call this function to start event handling. \sa quit(), exit() */ -- cgit v1.2.3 From bdc558019ac6660a32d20a428a8694ef6bd4d4d3 Mon Sep 17 00:00:00 2001 From: Sergio Ahumada Date: Fri, 18 Oct 2013 18:40:39 +0200 Subject: tests: Replace Q_OS_MACX -> Q_OS_OSX Use the correct identifier for the OS X operating system. Change-Id: I7158a6b77e5e7418bc6b0a565f003500820a346d Reviewed-by: Jake Petroules Reviewed-by: Eike Ziller --- tests/auto/corelib/io/qsettings/tst_qsettings.cpp | 10 +++++----- tests/auto/gui/kernel/qwindow/tst_qwindow.cpp | 2 +- tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp | 4 ++-- tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp | 2 +- .../kernel/qnetworkproxyfactory/tst_qnetworkproxyfactory.cpp | 2 +- tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/tests/auto/corelib/io/qsettings/tst_qsettings.cpp b/tests/auto/corelib/io/qsettings/tst_qsettings.cpp index f0fa860686..dc83cf2fc4 100644 --- a/tests/auto/corelib/io/qsettings/tst_qsettings.cpp +++ b/tests/auto/corelib/io/qsettings/tst_qsettings.cpp @@ -514,20 +514,20 @@ void tst_QSettings::ctor() QSettings settings5(format, QSettings::UserScope, "SoftWare.ORG", "killerApp"); if (format == QSettings::NativeFormat) { #if defined(Q_OS_WIN) || defined(Q_OS_DARWIN) -# ifdef Q_OS_MACX +# ifdef Q_OS_OSX if (QSysInfo::MacintoshVersion == QSysInfo::MV_10_8) QEXPECT_FAIL("native", "See QTBUG-32655", Continue); -# endif // Q_OS_MACX +# endif // Q_OS_OSX QCOMPARE(settings5.value("key 1").toString(), QString("gurgle")); #else QVERIFY(!settings5.contains("key 1")); #endif } else { #if defined(Q_OS_WIN) || defined(Q_OS_DARWIN) -# ifdef Q_OS_MACX +# ifdef Q_OS_OSX if (QSysInfo::MacintoshVersion == QSysInfo::MV_10_8) QEXPECT_FAIL("", "See QTBUG-32655", Continue); -# endif // Q_OS_MACX +# endif // Q_OS_OSX QCOMPARE(settings5.value("key 1").toString(), QString("gurgle")); #else QVERIFY(!settings5.contains("key 1")); @@ -3183,7 +3183,7 @@ void tst_QSettings::rainersSyncBugOnMac() { QSettings s3(format, QSettings::UserScope, "software.org", "KillerAPP"); -#ifdef Q_OS_MACX +#ifdef Q_OS_OSX if (QSysInfo::MacintoshVersion == QSysInfo::MV_10_8) QEXPECT_FAIL("native", "See QTBUG-32655", Continue); #endif diff --git a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp index 7ad7880330..c4983f4462 100644 --- a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp +++ b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp @@ -223,7 +223,7 @@ void tst_QWindow::positioning() window.setWindowState(Qt::WindowFullScreen); QCoreApplication::processEvents(); -#ifdef Q_OS_MACX +#ifdef Q_OS_OSX QEXPECT_FAIL("", "Multiple failures in this test on Mac OS X, see QTBUG-23059", Abort); #endif QTRY_COMPARE(window.received(QEvent::Resize), 2); diff --git a/tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp b/tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp index 3f6eaae89b..3d2cde5fd3 100644 --- a/tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp +++ b/tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp @@ -502,10 +502,10 @@ void tst_QGlyphRun::drawMultiScriptText2() drawGlyphs.save("drawMultiScriptText2_drawGlyphIndexes.png"); #endif -#ifdef Q_OS_MACX +#ifdef Q_OS_OSX if (drawGlyphs.toImage() != textLayoutDraw.toImage()) QEXPECT_FAIL("", "See QTBUG-32690", Continue); -#endif // Q_OS_MACX +#endif // Q_OS_OSX QCOMPARE(drawGlyphs, textLayoutDraw); } diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp index 0e8d9fa2a3..2826c497df 100644 --- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -7588,7 +7588,7 @@ void tst_QNetworkReply::backgroundRequestInterruption() QNetworkSessionPrivate::setUsagePolicies(*const_cast(session.data()), original); QVERIFY(reply->isFinished()); -#ifdef Q_OS_MACX +#ifdef Q_OS_OSX if (QSysInfo::MacintoshVersion == QSysInfo::MV_10_8) QEXPECT_FAIL("ftp, bg, nobg", "See QTBUG-32435", Abort); #endif diff --git a/tests/auto/network/kernel/qnetworkproxyfactory/tst_qnetworkproxyfactory.cpp b/tests/auto/network/kernel/qnetworkproxyfactory/tst_qnetworkproxyfactory.cpp index 9e03884e4e..1271bf38ca 100644 --- a/tests/auto/network/kernel/qnetworkproxyfactory/tst_qnetworkproxyfactory.cpp +++ b/tests/auto/network/kernel/qnetworkproxyfactory/tst_qnetworkproxyfactory.cpp @@ -380,7 +380,7 @@ void tst_QNetworkProxyFactory::genericSystemProxy() QFETCH(int, port); // The generic system proxy is only available on the following platforms -#if (!defined Q_OS_BLACKBERRY) && (!defined Q_OS_WIN) && (!defined Q_OS_MACX) +#if (!defined Q_OS_BLACKBERRY) && (!defined Q_OS_WIN) && (!defined Q_OS_OSX) qputenv(envVar, url); const QList systemProxy = QNetworkProxyFactory::systemProxyForQuery(); QCOMPARE(systemProxy.size(), 1); diff --git a/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp b/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp index c240b5eb35..4506d0af14 100644 --- a/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp +++ b/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp @@ -439,7 +439,7 @@ void tst_QWizard::setPixmap() QVERIFY(wizard.pixmap(QWizard::BannerPixmap).isNull()); QVERIFY(wizard.pixmap(QWizard::LogoPixmap).isNull()); QVERIFY(wizard.pixmap(QWizard::WatermarkPixmap).isNull()); -#ifdef Q_OS_MACX +#ifdef Q_OS_OSX QVERIFY(wizard.pixmap(QWizard::BackgroundPixmap).isNull() == false); #else QVERIFY(wizard.pixmap(QWizard::BackgroundPixmap).isNull()); @@ -448,7 +448,7 @@ void tst_QWizard::setPixmap() QVERIFY(page->pixmap(QWizard::BannerPixmap).isNull()); QVERIFY(page->pixmap(QWizard::LogoPixmap).isNull()); QVERIFY(page->pixmap(QWizard::WatermarkPixmap).isNull()); -#ifdef Q_OS_MACX +#ifdef Q_OS_OSX QVERIFY(wizard.pixmap(QWizard::BackgroundPixmap).isNull() == false); #else QVERIFY(page->pixmap(QWizard::BackgroundPixmap).isNull()); -- cgit v1.2.3 From 04771062a12b7e9244fb7d0581fcf8270075d766 Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Mon, 21 Oct 2013 10:59:14 +0200 Subject: changelog: add note about TLS session tickets Change-Id: I154a56ff85adb8d43ddb730d91d2c59f129f7a26 Reviewed-by: Richard J. Moore --- dist/changes-5.2.0 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dist/changes-5.2.0 b/dist/changes-5.2.0 index ea15295cad..a3a7db8190 100644 --- a/dist/changes-5.2.0 +++ b/dist/changes-5.2.0 @@ -88,6 +88,8 @@ QtGui QtNetwork --------- +- API was added to store and resume TLS session tickets. + - The minimum support openssl version has been increased to openssl 1.0. The code to support older versions has not been removed, but is no longer supported. -- cgit v1.2.3 From 13035f7fd648c3c4217620695aae033dfbf37b8a Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 16 Oct 2013 14:42:44 +0200 Subject: iOS: default_post: let xcodebuild_distclean depend on xcodebuild_clean Otherwise, make would upon distclean first remove the xcode project, then try to do xcodebuild distclean. xcodebuild would then complain about a missing project. Change-Id: I0a9a6af6d86d1a95e37f4bbafa38c63d892bf1cc Reviewed-by: Oswald Buddenhagen --- mkspecs/macx-ios-clang/features/default_post.prf | 1 + 1 file changed, 1 insertion(+) diff --git a/mkspecs/macx-ios-clang/features/default_post.prf b/mkspecs/macx-ios-clang/features/default_post.prf index fa81ae406d..0d38c058c9 100644 --- a/mkspecs/macx-ios-clang/features/default_post.prf +++ b/mkspecs/macx-ios-clang/features/default_post.prf @@ -44,6 +44,7 @@ equals(TEMPLATE, app) { # And distclean xcodebuild_distclean.commands = "$(DEL_FILE) -R $$TARGET_XCODE_PROJECT_DIR" + xcodebuild_distclean.depends = xcodebuild_clean QMAKE_EXTRA_TARGETS += xcodebuild_distclean distclean.depends = xcodebuild_distclean QMAKE_EXTRA_TARGETS += distclean -- cgit v1.2.3 From 690cf426f3a8c18d903e61228f65fa3b9e2a69d3 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Thu, 17 Oct 2013 19:24:28 +0200 Subject: Fix Q_ASSERT(!channels[0].isSocketBusy()); Since commit f30641a7 is has been possible to issue more than one host lookup request per HttpNetworkConnection. If the result was both an IPv4 and IPv6 address, and we get a second similar DNS reply, we end up triggering the assert in startNetworkLayerStateLookup(). This patch splits the InProgress state to HostLookupPending and the state of trying both IPv4 and IPv6. This makes it possible to ignore any new DNS replies received after the first succesfull one. Change-Id: I0b8d6b1582fdaed69dde5926019b60bb0cbd580d Reviewed-by: Peter Hartmann --- src/network/access/qhttpnetworkconnection.cpp | 18 ++++++++++-------- src/network/access/qhttpnetworkconnection_p.h | 5 +++-- src/network/access/qhttpnetworkconnectionchannel.cpp | 4 ++-- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index ba9e5cbdc4..e0996c4072 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -181,7 +181,7 @@ int QHttpNetworkConnectionPrivate::indexOf(QAbstractSocket *socket) const return 0; } -// If the connection is in the InProgress state channel errors should not always be +// If the connection is in the HostLookupPendening state channel errors should not always be // emitted. This function will check the status of the connection channels if we // have not decided the networkLayerState and will return true if the channel error // should be emitted by the channel. @@ -200,12 +200,12 @@ bool QHttpNetworkConnectionPrivate::shouldEmitChannelError(QAbstractSocket *sock } if (channelCount == 1) { - if (networkLayerState == QHttpNetworkConnectionPrivate::InProgress) + if (networkLayerState == HostLookupPending || networkLayerState == IPv4or6) networkLayerState = QHttpNetworkConnectionPrivate::Unknown; channels[0].close(); emitError = true; } else { - if (networkLayerState == QHttpNetworkConnectionPrivate::InProgress) { + if (networkLayerState == HostLookupPending || networkLayerState == IPv4or6) { if (channels[otherSocket].isSocketBusy() && (channels[otherSocket].state != QHttpNetworkConnectionChannel::ClosingState)) { // this was the first socket to fail. channels[i].close(); @@ -560,7 +560,7 @@ QHttpNetworkReply* QHttpNetworkConnectionPrivate::queueRequest(const QHttpNetwor // untill we have started the first connection attempt. So no // request will be started untill we know if IPv4 or IPv6 // should be used. - if (networkLayerState == Unknown || networkLayerState == InProgress) { + if (networkLayerState == Unknown || networkLayerState == HostLookupPending) { startHostInfoLookup(); } else if ( networkLayerState == IPv4 || networkLayerState == IPv6 ) { // this used to be called via invokeMethod and a QueuedConnection @@ -878,7 +878,7 @@ void QHttpNetworkConnectionPrivate::removeReply(QHttpNetworkReply *reply) void QHttpNetworkConnectionPrivate::_q_startNextRequest() { // If there is no network layer state decided we should not start any new requests. - if (networkLayerState == Unknown || networkLayerState == InProgress) + if (networkLayerState == Unknown || networkLayerState == HostLookupPending || networkLayerState == IPv4or6) return; // If the QHttpNetworkConnection is currently paused then bail out immediately @@ -986,7 +986,7 @@ void QHttpNetworkConnectionPrivate::readMoreLater(QHttpNetworkReply *reply) // lookup as then the hostinfo will already be in the cache. void QHttpNetworkConnectionPrivate::startHostInfoLookup() { - networkLayerState = InProgress; + networkLayerState = HostLookupPending; // check if we already now can decide if this is IPv4 or IPv6 QString lookupHost = hostName; @@ -1028,6 +1028,8 @@ void QHttpNetworkConnectionPrivate::_q_hostLookupFinished(QHostInfo info) bool bIpv4 = false; bool bIpv6 = false; bool foundAddress = false; + if (networkLayerState == IPv4 || networkLayerState == IPv6 || networkLayerState == IPv4or6) + return; foreach (const QHostAddress &address, info.addresses()) { if (address.protocol() == QAbstractSocket::IPv4Protocol) { @@ -1077,7 +1079,7 @@ void QHttpNetworkConnectionPrivate::startNetworkLayerStateLookup() Q_ASSERT(!channels[0].isSocketBusy()); Q_ASSERT(!channels[1].isSocketBusy()); - networkLayerState = InProgress; + networkLayerState = IPv4or6; channels[0].networkLayerPreference = QAbstractSocket::IPv4Protocol; channels[1].networkLayerPreference = QAbstractSocket::IPv6Protocol; @@ -1101,7 +1103,7 @@ void QHttpNetworkConnectionPrivate::startNetworkLayerStateLookup() else channels[0].ensureConnection(); } else { - networkLayerState = InProgress; + networkLayerState = IPv4or6; channels[0].networkLayerPreference = QAbstractSocket::AnyIPProtocol; channels[0].ensureConnection(); } diff --git a/src/network/access/qhttpnetworkconnection_p.h b/src/network/access/qhttpnetworkconnection_p.h index c54250f6ed..2aaaad24ac 100644 --- a/src/network/access/qhttpnetworkconnection_p.h +++ b/src/network/access/qhttpnetworkconnection_p.h @@ -165,9 +165,10 @@ public: enum NetworkLayerPreferenceState { Unknown, - InProgress, + HostLookupPending, IPv4, - IPv6 + IPv6, + IPv4or6 }; QHttpNetworkConnectionPrivate(const QString &hostName, quint16 port, bool encrypt); diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index da82fdf8d2..6e786893ed 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -1045,7 +1045,7 @@ void QHttpNetworkConnectionChannel::_q_disconnected() void QHttpNetworkConnectionChannel::_q_connected() { // For the Happy Eyeballs we need to check if this is the first channel to connect. - if (connection->d_func()->networkLayerState == QHttpNetworkConnectionPrivate::InProgress) { + if (connection->d_func()->networkLayerState == QHttpNetworkConnectionPrivate::HostLookupPending || connection->d_func()->networkLayerState == QHttpNetworkConnectionPrivate::IPv4or6) { if (connection->d_func()->delayedConnectionTimer.isActive()) connection->d_func()->delayedConnectionTimer.stop(); if (networkLayerPreference == QAbstractSocket::IPv4Protocol) @@ -1212,7 +1212,7 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket QPointer that = connection; QString errorString = connection->d_func()->errorDetail(errorCode, socket, socket->errorString()); - // In the InProgress state the channel should not emit the error. + // In the HostLookupPending state the channel should not emit the error. // This will instead be handled by the connection. if (!connection->d_func()->shouldEmitChannelError(socket)) return; -- cgit v1.2.3 From 7627f6739bf57c881f7976fb17ecf847b060ef5d Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Sun, 8 Sep 2013 07:49:51 +0300 Subject: Skip extra PKGCONFIG variables with empty value The fallback value is an empty string anyways. Change-Id: I77a2d3ad275321cb8b2e059fb6359f921cbc697c Reviewed-by: Oswald Buddenhagen --- qmake/generators/makefile.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index 3bc5f00cab..9ebaf60843 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -3240,7 +3240,8 @@ MakefileGenerator::writePkgConfigFile() } } } - t << var << "=" << val << endl; + if (!val.isEmpty()) + t << var << "=" << val << endl; } t << endl; -- cgit v1.2.3 From c9ad904af9b6009205f5d02779c407fcd65b8d12 Mon Sep 17 00:00:00 2001 From: Marcel Krems Date: Fri, 18 Oct 2013 11:56:45 +0200 Subject: Doc: Add missing \since 5.2 to QSizePolicy::retainSizeWhenHidden MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I461e8187810e564e06869df86b23cc40aeba72bd Reviewed-by: Thorbjørn Lund Martsum --- src/widgets/kernel/qsizepolicy.qdoc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/widgets/kernel/qsizepolicy.qdoc b/src/widgets/kernel/qsizepolicy.qdoc index 1c99131bc4..d82f3837f2 100644 --- a/src/widgets/kernel/qsizepolicy.qdoc +++ b/src/widgets/kernel/qsizepolicy.qdoc @@ -342,6 +342,7 @@ /*! \fn void QSizePolicy::retainSizeWhenHidden() const + \since 5.2 Returns if the layout should retain the widgets size when it is hidden. This is by default false. @@ -350,6 +351,7 @@ /*! \fn void QSizePolicy::setRetainSizeWhenHidden(bool retainSize) + \since 5.2 Set if a layout should retain the widgets size when it is hidden. If \a retainSize is true the layout will not be changed by hiding the widget. -- cgit v1.2.3 From 72a7882cec07a9ad187c9e1772fb08f59a4b9519 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Fri, 18 Oct 2013 12:36:47 +0200 Subject: Better QWindowContainer by not relying on native widgets. We change the behavior slightly from the initial implementation in 5.1. Forcing the use of native child widgets is causing massive performance issues so instead, we attach the embedded QWindow directly to the root window. The only exception is QScrollArea and QMdiArea which still enforces native windows for the entire parent chain to make clipping and stacking work. Task-number: QTBUG-34138 Change-Id: If713637bd4dce630552ace2f8ad6b2e86c063721 Reviewed-by: Lars Knoll --- src/widgets/kernel/qwidget.cpp | 16 ++ src/widgets/kernel/qwidget_p.h | 1 + src/widgets/kernel/qwindowcontainer.cpp | 173 ++++++++++++++++++--- src/widgets/kernel/qwindowcontainer_p.h | 5 + .../qwindowcontainer/tst_qwindowcontainer.cpp | 62 +++++++- 5 files changed, 230 insertions(+), 27 deletions(-) diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index f439edcf2e..abba2b455a 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -1594,6 +1594,7 @@ void QWidgetPrivate::createExtra() extra->autoFillBackground = 0; extra->nativeChildrenForced = 0; extra->inRenderWithPainter = 0; + extra->hasWindowContainer = false; extra->hasMask = 0; createSysExtra(); #ifdef QWIDGET_EXTRA_DEBUG @@ -6543,6 +6544,9 @@ void QWidget::move(const QPoint &p) data->crect.moveTopLeft(p); // no frame yet setAttribute(Qt::WA_PendingMoveEvent); } + + if (d->extra && d->extra->hasWindowContainer) + QWindowContainer::parentWasMoved(this); } /*! \fn void QWidget::resize(int w, int h) @@ -6581,6 +6585,9 @@ void QWidget::setGeometry(const QRect &r) setAttribute(Qt::WA_PendingMoveEvent); setAttribute(Qt::WA_PendingResizeEvent); } + + if (d->extra && d->extra->hasWindowContainer) + QWindowContainer::parentWasMoved(this); } /*! @@ -9715,6 +9722,9 @@ void QWidget::setParent(QWidget *parent, Qt::WindowFlags f) ancestorProxy->d_func()->embedSubWindow(this); } #endif + + if (d->extra && d->extra->hasWindowContainer) + QWindowContainer::parentWasChanged(this); } /*! @@ -10747,6 +10757,9 @@ void QWidget::raise() if (testAttribute(Qt::WA_WState_Created)) d->raise_sys(); + if (d->extra && d->extra->hasWindowContainer) + QWindowContainer::parentWasRaised(this); + QEvent e(QEvent::ZOrderChange); QApplication::sendEvent(this, &e); } @@ -10781,6 +10794,9 @@ void QWidget::lower() if (testAttribute(Qt::WA_WState_Created)) d->lower_sys(); + if (d->extra && d->extra->hasWindowContainer) + QWindowContainer::parentWasLowered(this); + QEvent e(QEvent::ZOrderChange); QApplication::sendEvent(this, &e); } diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h index cc740034fc..df40908c00 100644 --- a/src/widgets/kernel/qwidget_p.h +++ b/src/widgets/kernel/qwidget_p.h @@ -254,6 +254,7 @@ struct QWExtra { uint nativeChildrenForced : 1; uint inRenderWithPainter : 1; uint hasMask : 1; + uint hasWindowContainer : 1; // *************************** Platform specific values (bit fields first) ********** #if defined(Q_WS_WIN) // <----------------------------------------------------------- WIN diff --git a/src/widgets/kernel/qwindowcontainer.cpp b/src/widgets/kernel/qwindowcontainer.cpp index b02b05552f..6914f64f8e 100644 --- a/src/widgets/kernel/qwindowcontainer.cpp +++ b/src/widgets/kernel/qwindowcontainer.cpp @@ -42,6 +42,10 @@ #include "qwindowcontainer_p.h" #include "qwidget_p.h" #include +#include + +#include +#include QT_BEGIN_NAMESPACE @@ -50,11 +54,67 @@ class QWindowContainerPrivate : public QWidgetPrivate public: Q_DECLARE_PUBLIC(QWindowContainer) - QWindowContainerPrivate() : window(0), oldFocusWindow(0) { } + QWindowContainerPrivate() + : window(0) + , oldFocusWindow(0) + , usesNativeWidgets(false) + { + } + ~QWindowContainerPrivate() { } + static QWindowContainerPrivate *get(QWidget *w) { + QWindowContainer *wc = qobject_cast(w); + if (wc) + return wc->d_func(); + return 0; + } + + void updateGeometry() { + Q_Q(QWindowContainer); + if (usesNativeWidgets) + window->setGeometry(q->rect()); + else + window->setGeometry(QRect(q->mapTo(q->window(), QPoint()), q->size())); + } + + void updateUsesNativeWidgets() + { + if (usesNativeWidgets || window->parent() == 0) + return; + Q_Q(QWindowContainer); + QWidget *p = q->parentWidget(); + while (p) { + if (qobject_cast(p) != 0 + || qobject_cast(p) != 0) { + q->winId(); + usesNativeWidgets = true; + break; + } + p = p->parentWidget(); + } + } + + void markParentChain() { + Q_Q(QWindowContainer); + QWidget *p = q; + while (p) { + QWidgetPrivate *d = static_cast(QWidgetPrivate::get(p)); + d->createExtra(); + d->extra->hasWindowContainer = true; + p = p->parentWidget(); + } + } + + bool isStillAnOrphan() const { + return window->parent() == &fakeParent; + } + QPointer window; QWindow *oldFocusWindow; + QWindow fakeParent; + + uint usesNativeWidgets : 1; }; @@ -78,6 +138,14 @@ public: be removed from the window container with a call to QWindow::setParent(). + The window container is attached as a native child window to the + toplevel window it is a child of. When a window container is used + as a child of a QAbstractScrollArea or QMdiArea, it will + create a \l {Native Widgets vs Alien Widgets} {native window} for + every widget in its parent chain to allow for proper stacking and + clipping in this use case. Applications with many native child + windows may suffer from performance issues. + The window container has a number of known limitations: \list @@ -86,11 +154,6 @@ public: widget hierarchy as an opaque box. The stacking order of multiple overlapping window container instances is undefined. - \li Window Handles; The window container will explicitly invoke - winId() which will force the use of native window handles - inside the application. See \l {Native Widgets vs Alien Widgets} - {QWidget documentation} for more details. - \li Rendering Integration; The window container does not interoperate with QGraphicsProxyWidget, QWidget::render() or similar functionality. @@ -132,13 +195,7 @@ QWindowContainer::QWindowContainer(QWindow *embeddedWindow, QWidget *parent, Qt: } d->window = embeddedWindow; - - // We force this window to become a native window and reparent the - // window directly to it. This is done so that the order in which - // the QWindowContainer is added to a QWidget tree and when it - // gets a window does not matter. - winId(); - d->window->setParent(windowHandle()); + d->window->setParent(&d->fakeParent); connect(QGuiApplication::instance(), SIGNAL(focusWindowChanged(QWindow *)), this, SLOT(focusWindowChanged(QWindow *))); } @@ -167,8 +224,6 @@ void QWindowContainer::focusWindowChanged(QWindow *focusWindow) d->oldFocusWindow = focusWindow; } - - /*! \internal */ @@ -190,22 +245,38 @@ bool QWindowContainer::event(QEvent *e) // The only thing we are interested in is making sure our sizes stay // in sync, so do a catch-all case. case QEvent::Resize: + d->updateGeometry(); + break; case QEvent::Move: + d->updateGeometry(); + break; case QEvent::PolishRequest: - d->window->setGeometry(0, 0, width(), height()); + d->updateGeometry(); break; case QEvent::Show: - d->window->show(); + d->updateUsesNativeWidgets(); + if (d->isStillAnOrphan()) { + d->window->setParent(d->usesNativeWidgets + ? windowHandle() + : window()->windowHandle()); + } + if (d->window->parent()) { + d->markParentChain(); + d->window->show(); + } break; case QEvent::Hide: - d->window->hide(); + if (d->window->parent()) + d->window->hide(); break; case QEvent::FocusIn: - if (d->oldFocusWindow != d->window) { - d->window->requestActivate(); - } else { - QWidget *next = nextInFocusChain(); - next->setFocus(); + if (d->window->parent()) { + if (d->oldFocusWindow != d->window) { + d->window->requestActivate(); + } else { + QWidget *next = nextInFocusChain(); + next->setFocus(); + } } break; default: @@ -215,4 +286,60 @@ bool QWindowContainer::event(QEvent *e) return QWidget::event(e); } +typedef void (*qwindowcontainer_traverse_callback)(QWidget *parent); +static void qwindowcontainer_traverse(QWidget *parent, qwindowcontainer_traverse_callback callback) +{ + const QObjectList &children = parent->children(); + for (int i=0; i(children.at(i)); + if (w) { + QWidgetPrivate *wd = static_cast(QWidgetPrivate::get(w)); + if (wd->extra && wd->extra->hasWindowContainer) + callback(w); + } + } +} + +void QWindowContainer::parentWasChanged(QWidget *parent) +{ + if (QWindowContainerPrivate *d = QWindowContainerPrivate::get(parent)) { + if (d->window->parent()) { + d->updateUsesNativeWidgets(); + d->markParentChain(); + d->window->setParent(d->usesNativeWidgets + ? parent->windowHandle() + : parent->window()->windowHandle()); + d->updateGeometry(); + } + } + qwindowcontainer_traverse(parent, parentWasChanged); +} + +void QWindowContainer::parentWasMoved(QWidget *parent) +{ + if (QWindowContainerPrivate *d = QWindowContainerPrivate::get(parent)) { + if (d->window->parent()) + d->updateGeometry(); + } + qwindowcontainer_traverse(parent, parentWasMoved); +} + +void QWindowContainer::parentWasRaised(QWidget *parent) +{ + if (QWindowContainerPrivate *d = QWindowContainerPrivate::get(parent)) { + if (d->window->parent()) + d->window->raise(); + } + qwindowcontainer_traverse(parent, parentWasRaised); +} + +void QWindowContainer::parentWasLowered(QWidget *parent) +{ + if (QWindowContainerPrivate *d = QWindowContainerPrivate::get(parent)) { + if (d->window->parent()) + d->window->lower(); + } + qwindowcontainer_traverse(parent, parentWasLowered); +} + QT_END_NAMESPACE diff --git a/src/widgets/kernel/qwindowcontainer_p.h b/src/widgets/kernel/qwindowcontainer_p.h index 37c023fc1d..e2446bef42 100644 --- a/src/widgets/kernel/qwindowcontainer_p.h +++ b/src/widgets/kernel/qwindowcontainer_p.h @@ -57,6 +57,11 @@ public: explicit QWindowContainer(QWindow *embeddedWindow, QWidget *parent = 0, Qt::WindowFlags f = 0); ~QWindowContainer(); + static void parentWasChanged(QWidget *parent); + static void parentWasMoved(QWidget *parent); + static void parentWasRaised(QWidget *parent); + static void parentWasLowered(QWidget *parent); + protected: bool event(QEvent *ev); diff --git a/tests/auto/widgets/kernel/qwindowcontainer/tst_qwindowcontainer.cpp b/tests/auto/widgets/kernel/qwindowcontainer/tst_qwindowcontainer.cpp index 2d9cb98e27..c17a03e058 100644 --- a/tests/auto/widgets/kernel/qwindowcontainer/tst_qwindowcontainer.cpp +++ b/tests/auto/widgets/kernel/qwindowcontainer/tst_qwindowcontainer.cpp @@ -68,8 +68,6 @@ public: int numberOfObscures; }; - - class tst_QWindowContainer: public QObject { Q_OBJECT @@ -81,6 +79,7 @@ private slots: void testBehindTheScenesDeletion(); void testUnparenting(); void testActivation(); + void testAncestorChange(); }; @@ -188,6 +187,7 @@ void tst_QWindowContainer::testActivation() root.show(); root.activateWindow(); + QVERIFY(QTest::qWaitForWindowExposed(&root)); QVERIFY(QTest::qWaitForWindowActive(root.windowHandle())); QVERIFY(QGuiApplication::focusWindow() == root.windowHandle()); @@ -204,8 +204,7 @@ void tst_QWindowContainer::testActivation() QTest::qWait(100); window->requestActivate(); - QVERIFY(QTest::qWaitForWindowActive(window)); - QVERIFY(QGuiApplication::focusWindow() == window); + QTRY_VERIFY(QGuiApplication::focusWindow() == window); // Verify that all states in the root widget still indicate it is active QVERIFY(root.windowHandle()->isActive()); @@ -231,6 +230,61 @@ void tst_QWindowContainer::testUnparenting() QVERIFY(!window->isVisible()); } +void tst_QWindowContainer::testAncestorChange() +{ + QWidget root; + QWidget *left = new QWidget(&root); + QWidget *right = new QWidget(&root); + + root.setGeometry(0, 0, 200, 100); + left->setGeometry(0, 0, 100, 100); + right->setGeometry(100, 0, 100, 100); + + QWindow *window = new QWindow(); + QWidget *container = QWidget::createWindowContainer(window, left); + container->setGeometry(0, 0, 100, 100); + + // Root + // + left + // | + container + // | + window + // + right + root.show(); + QVERIFY(QTest::qWaitForWindowExposed(&root)); + QCOMPARE(window->geometry(), QRect(0, 0, 100, 100)); + + container->setParent(right); + // Root + // + left + // + right + // + container + // + window + QCOMPARE(window->geometry(), QRect(100, 0, 100, 100)); + + QWidget *newRoot = new QWidget(&root); + newRoot->setGeometry(50, 50, 200, 200); + right->setParent(newRoot); + // Root + // + left + // + newRoot + // + right + // + container + // + window + QCOMPARE(window->geometry(), QRect(150, 50, 100, 100)); + newRoot->move(0, 0); + QCOMPARE(window->geometry(), QRect(100, 0, 100, 100)); + + newRoot->setParent(0); + newRoot->setGeometry(100, 100, 200, 200); + newRoot->show(); + QVERIFY(QTest::qWaitForWindowExposed(newRoot)); + // newRoot + // + right + // + container + // + window + QCOMPARE(window->geometry(), QRect(100, 0, 100, 100)); +} + QTEST_MAIN(tst_QWindowContainer) #include "tst_qwindowcontainer.moc" -- cgit v1.2.3 From 9b187bcd6a256b53cc2fb8550da64b30b0cc5760 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Mon, 21 Oct 2013 12:54:45 +0200 Subject: Fix compilation with latest MinGW-w64 (release 3) Now that MinGW-w64 fixed the headers the old hack actually break stuff. Change-Id: I1f60b9176982f6c07e01f3960bc1d7e70d7f9481 Reviewed-by: Friedemann Kleint --- src/plugins/platforms/windows/qwindowsdialoghelpers.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp index 0bf6838d9e..8c3b7e17c6 100644 --- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp +++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp @@ -1766,7 +1766,9 @@ static int CALLBACK xpFileDialogGetExistingDirCallbackProc(HWND hwnd, UINT uMsg, return dialog->existingDirCallback(hwnd, uMsg, lParam); } -#ifdef Q_CC_MINGW +/* The correct declaration of the SHGetPathFromIDList symbol is + * being used in mingw-w64 as of r6215, which is a v3 snapshot. */ +#if defined(Q_CC_MINGW) && (!defined(__MINGW64_VERSION_MAJOR) || _MINGW64_VERSION_MAJOR < 3) typedef ITEMIDLIST *qt_LpItemIdList; #else typedef PIDLIST_ABSOLUTE qt_LpItemIdList; -- cgit v1.2.3 From 377c7575a7e8acc6030520cb36fe66da3ce43a93 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 18 Oct 2013 14:37:18 +0200 Subject: don't load wayland-scanner for all projects on linux it's wasteful, given that exactly one add-on module (and most probably nobody else) needs it. i'd do the same with yacc and lex, but i suspect this would cause quite an uproar. Change-Id: Ic2a6ca19e829393835f824e31cd0893e78c3fd39 Reviewed-by: Joerg Bornemann --- mkspecs/features/unix/default_pre.prf | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 mkspecs/features/unix/default_pre.prf diff --git a/mkspecs/features/unix/default_pre.prf b/mkspecs/features/unix/default_pre.prf deleted file mode 100644 index d978d14166..0000000000 --- a/mkspecs/features/unix/default_pre.prf +++ /dev/null @@ -1,4 +0,0 @@ -linux*:CONFIG = wayland-scanner $$CONFIG - -load(default_pre) - -- cgit v1.2.3 From 163bbeb2181bc66683bb836542dc1ea2bcded1fd Mon Sep 17 00:00:00 2001 From: Matt Hoosier Date: Thu, 17 Oct 2013 08:47:46 -0500 Subject: Detect pointer size at configure-time on Windows-hosted builds The configure-time procedure used on Windows does not currently perform the same tests to determine the width of a pointer as are performed on Unix-based builds. This causes QT_POINTER_SIZE to be undefined in the generated qconfig.h file. This in turn breaks compilation of various Qt modules such as QtDeclarative. This patch adds the same level of support for automatically determining the target platform's pointer size, as is currently offered to Unix users. Change-Id: I93838c1759b14089ba9f4daf442048fb5c8da738 Reviewed-by: Oswald Buddenhagen Reviewed-by: Joerg Bornemann --- config.tests/unix/ptrsize/ptrsizetest.pro | 1 + tools/configure/configureapp.cpp | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/config.tests/unix/ptrsize/ptrsizetest.pro b/config.tests/unix/ptrsize/ptrsizetest.pro index 045a759ec9..a7ae38a5d9 100644 --- a/config.tests/unix/ptrsize/ptrsizetest.pro +++ b/config.tests/unix/ptrsize/ptrsizetest.pro @@ -1,2 +1,3 @@ SOURCES = ptrsizetest.cpp CONFIG -= qt dylib +CONFIG += debug console diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 757de7b3b0..c3382a5e0a 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -2353,6 +2353,11 @@ void Configure::autoDetection() if (i.value() == "auto") i.value() = defaultTo(i.key()); } + + if (tryCompileProject("unix/ptrsize")) + dictionary["QT_POINTER_SIZE"] = "8"; + else + dictionary["QT_POINTER_SIZE"] = "4"; } bool Configure::verifyConfiguration() @@ -3411,6 +3416,8 @@ void Configure::generateConfigfiles() if (dictionary["REDUCE_RELOCATIONS"] == "yes") qconfigList += "QT_REDUCE_RELOCATIONS"; if (dictionary["QT_GETIFADDRS"] == "no") qconfigList += "QT_NO_GETIFADDRS"; + qconfigList += QString("QT_POINTER_SIZE=%1").arg(dictionary["QT_POINTER_SIZE"]); + qconfigList.sort(); for (int i = 0; i < qconfigList.count(); ++i) tmpStream << addDefine(qconfigList.at(i)); -- cgit v1.2.3 From a83983d8617cba0caaae2cb2d6caf82b8e4f50a2 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Tue, 22 Oct 2013 17:00:45 +0200 Subject: QTextHtmlParser: restore the default link color from app palette The default link color used to be resolved to the link color of the application palette, but got lost during the Qt 5 modularization (see commits 7351a43 and 3f9a7f9). Task-number: QTBUG-28998 Change-Id: I7f07427f6c03f83c557100938ad9f7a39349d303 Reviewed-by: Olivier Goffart --- src/gui/text/qtexthtmlparser.cpp | 4 ++-- .../gui/text/qtextdocument/tst_qtextdocument.cpp | 28 ++++++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/gui/text/qtexthtmlparser.cpp b/src/gui/text/qtexthtmlparser.cpp index 5292ba20a2..a131503b85 100644 --- a/src/gui/text/qtexthtmlparser.cpp +++ b/src/gui/text/qtexthtmlparser.cpp @@ -46,7 +46,7 @@ #include #include #include -#include +#include #include "qtextdocument.h" #include "qtextformat_p.h" @@ -1066,7 +1066,7 @@ void QTextHtmlParserNode::initializeProperties(const QTextHtmlParserNode *parent && !attributes.at(i + 1).isEmpty()) { hasHref = true; charFormat.setUnderlineStyle(QTextCharFormat::SingleUnderline); - charFormat.setForeground(Qt::blue); + charFormat.setForeground(QGuiApplication::palette().link()); } } diff --git a/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp b/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp index 307e5a6210..b065f537f7 100644 --- a/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp +++ b/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp @@ -54,6 +54,7 @@ #include #include #include +#include #include #include #include @@ -187,6 +188,9 @@ private slots: void QTBUG27354_spaceAndSoftSpace(); void cssInheritance(); + + void QTBUG28998_linkColor(); + private: void backgroundImage_checkExpectedHtml(const QTextDocument &doc); @@ -2974,5 +2978,29 @@ void tst_QTextDocument::cssInheritance() } } +void tst_QTextDocument::QTBUG28998_linkColor() +{ + QPalette pal; + pal.setColor(QPalette::Link, QColor("tomato")); + QGuiApplication::setPalette(pal); + + QTextDocument doc; + doc.setHtml("Qt"); + + QCOMPARE(doc.blockCount(), 1); + QTextBlock block = doc.firstBlock(); + QVERIFY(block.isValid()); + + QTextFragment fragment = block.begin().fragment(); + QVERIFY(fragment.isValid()); + + QTextCharFormat format = fragment.charFormat(); + QVERIFY(format.isValid()); + QVERIFY(format.isAnchor()); + QCOMPARE(format.anchorHref(), QStringLiteral("http://www.qt-project.org")); + + QCOMPARE(format.foreground(), pal.link()); +} + QTEST_MAIN(tst_QTextDocument) #include "tst_qtextdocument.moc" -- cgit v1.2.3 From bd3f3f31bf15f966d9d1ae0974fbc4028e6ed17e Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Tue, 22 Oct 2013 17:57:46 +0200 Subject: Android: Make platform menu more robust Don't crash and lock up the whole device when people try to remove menu items that don't exist. Task-number: QTBUG-34246 Change-Id: I4396d252c5af93e021c9e218dbab7c0e7f190d9d Reviewed-by: BogDan Vatra --- src/plugins/platforms/android/src/qandroidplatformmenu.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/android/src/qandroidplatformmenu.cpp b/src/plugins/platforms/android/src/qandroidplatformmenu.cpp index 36247e86f9..253c22a12f 100644 --- a/src/plugins/platforms/android/src/qandroidplatformmenu.cpp +++ b/src/plugins/platforms/android/src/qandroidplatformmenu.cpp @@ -67,9 +67,11 @@ void QAndroidPlatformMenu::insertMenuItem(QPlatformMenuItem *menuItem, QPlatform void QAndroidPlatformMenu::removeMenuItem(QPlatformMenuItem *menuItem) { QMutexLocker lock(&m_menuItemsMutex); - m_menuItems.erase(qFind(m_menuItems.begin(), - m_menuItems.end(), - static_cast(menuItem))); + PlatformMenuItemsType::iterator it = qFind(m_menuItems.begin(), + m_menuItems.end(), + static_cast(menuItem)); + if (it != m_menuItems.end()) + m_menuItems.erase(it); } void QAndroidPlatformMenu::syncMenuItem(QPlatformMenuItem *menuItem) -- cgit v1.2.3 From aa7fa093126f4ce9204b0d8efa7f9e8762847905 Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Tue, 22 Oct 2013 14:06:29 +0200 Subject: Android/LinuxFb: fix QWidget::showFullScreen() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, showFullScreen() had a race condition: it depended on QFbScreen::setGeometry() being called after the window state was set (that would trigger QPlatformScreen::resizeMaximizedWindows(), which was the only part of the code that reacted to WindowFullScreen). On Android this caused random behaviour. Task-number: QTBUG-33294 Change-Id: I228e6af4139af1a47387e7d80757d7b46e859580 Reviewed-by: Jørgen Lind Reviewed-by: Laszlo Agocs --- src/platformsupport/fbconvenience/qfbwindow.cpp | 20 ++++++++++++++++++++ src/platformsupport/fbconvenience/qfbwindow_p.h | 3 +++ 2 files changed, 23 insertions(+) diff --git a/src/platformsupport/fbconvenience/qfbwindow.cpp b/src/platformsupport/fbconvenience/qfbwindow.cpp index 246f50b4a9..8b6186db79 100644 --- a/src/platformsupport/fbconvenience/qfbwindow.cpp +++ b/src/platformsupport/fbconvenience/qfbwindow.cpp @@ -77,6 +77,26 @@ void QFbWindow::setGeometry(const QRect &rect) QPlatformWindow::setGeometry(rect); } +void QFbWindow::setVisible(bool visible) +{ + if (visible) { + if (mWindowState & Qt::WindowFullScreen) + setGeometry(platformScreen()->geometry()); + else if (mWindowState & Qt::WindowMaximized) + setGeometry(platformScreen()->availableGeometry()); + } + QPlatformWindow::setVisible(visible); +} + + +void QFbWindow::setWindowState(Qt::WindowState state) +{ + QPlatformWindow::setWindowState(state); + mWindowState = state; + platformScreen()->invalidateRectCache(); +} + + void QFbWindow::setWindowFlags(Qt::WindowFlags flags) { mWindowFlags = flags; diff --git a/src/platformsupport/fbconvenience/qfbwindow_p.h b/src/platformsupport/fbconvenience/qfbwindow_p.h index 25e2afca14..5ad921b0d7 100644 --- a/src/platformsupport/fbconvenience/qfbwindow_p.h +++ b/src/platformsupport/fbconvenience/qfbwindow_p.h @@ -59,7 +59,9 @@ public: virtual void lower(); virtual void setGeometry(const QRect &rect); + virtual void setVisible(bool visible); + virtual void setWindowState(Qt::WindowState state); virtual void setWindowFlags(Qt::WindowFlags type); virtual Qt::WindowFlags windowFlags() const; @@ -78,6 +80,7 @@ protected: QFbBackingStore *mBackingStore; QRect mOldGeometry; Qt::WindowFlags mWindowFlags; + Qt::WindowState mWindowState; WId mWindowId; }; -- cgit v1.2.3 From 5d8a882c11201a29475c5ea71cfb76c9de6573f5 Mon Sep 17 00:00:00 2001 From: Jonathan Liu Date: Wed, 23 Oct 2013 00:28:17 +1100 Subject: Fix misaligned selection region with text when centered If the text is centered, the x/y position in the selection QRectF may be a multiple of 0.5 which is rounded up. This rounding causes misalignment of the selection region with the text. The alignment is fixed by using qFloor on the x and y components. Task-number: QTBUG-34218 Task-number: QTBUG-34234 Change-Id: I4f2fadeb38602f62a93773c6e5faecf03b28069f Reviewed-by: Gunnar Sletta --- src/gui/text/qtextlayout.cpp | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index 54d337ecc5..66341e186a 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -44,6 +44,7 @@ #include #include +#include #include #include #include @@ -946,15 +947,23 @@ static void addSelectedRegionsToPath(QTextEngine *eng, int lineNumber, const QPo continue; } - if (lastSelectionWidth > 0) - region->addRect(boundingRect & QRectF(lastSelectionX.toReal(), selectionY, lastSelectionWidth.toReal(), lineHeight)); + if (lastSelectionWidth > 0) { + QRectF rect = boundingRect & QRectF(lastSelectionX.toReal(), selectionY, lastSelectionWidth.toReal(), lineHeight); + rect.moveLeft(qFloor(rect.left())); + rect.moveTop(qFloor(rect.top())); + region->addRect(rect); + } lastSelectionX = selectionX; lastSelectionWidth = selectionWidth; } } - if (lastSelectionWidth > 0) - region->addRect(boundingRect & QRectF(lastSelectionX.toReal(), selectionY, lastSelectionWidth.toReal(), lineHeight)); + if (lastSelectionWidth > 0) { + QRectF rect = boundingRect & QRectF(lastSelectionX.toReal(), selectionY, lastSelectionWidth.toReal(), lineHeight); + rect.moveLeft(qFloor(rect.left())); + rect.moveTop(qFloor(rect.top())); + region->addRect(rect); + } } static inline QRectF clipIfValid(const QRectF &rect, const QRectF &clip) @@ -2077,7 +2086,7 @@ static void setPenAndDrawBackground(QPainter *p, const QPen &defaultPen, const Q QBrush bg = chf.background(); if (bg.style() != Qt::NoBrush && !chf.property(SuppressBackground).toBool()) - p->fillRect(r, bg); + p->fillRect(QRectF(qFloor(r.x()), qFloor(r.y()), r.width(), r.height()), bg); if (c.style() != Qt::NoBrush) { p->setPen(QPen(c, 0)); } -- cgit v1.2.3 From cbcfbd798fc2dec55217a5ab6fb34b67e0f73ba3 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Wed, 23 Oct 2013 09:57:59 +0200 Subject: Rely on isLayered() to decide layering The logic here was a bit broken. Every QWindow has an opacity which is 1 by default so the expose was hit for every single window, regardless of it being layered or not. Change-Id: I04873cd5db1cd147708e7de140f5947d3a01e9e1 Reviewed-by: Friedemann Kleint --- src/plugins/platforms/windows/qwindowswindow.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index be739d0551..1909e0313b 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -1056,9 +1056,10 @@ void QWindowsWindow::setVisible(bool visible) // When the window is layered, we won't get WM_PAINT, and "we" are in control // over the rendering of the window // There is nobody waiting for this, so we don't need to flush afterwards. - QWindow *w = window(); - if (w->format().hasAlpha() || qFuzzyCompare(w->opacity(), qreal(1))) + if (isLayered()) { + QWindow *w = window(); fireExpose(QRect(0, 0, w->width(), w->height())); + } } else { if (hasMouseCapture()) -- cgit v1.2.3 From 744a2018531049cc5282509ed5ff6dc5035df19e Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Tue, 15 Oct 2013 09:07:42 +0300 Subject: Move untranslatable stings to AndroidManifest.xml strings.xml file is used to store strings that can/should be internationalized. Change-Id: I2fc305b6917752e9f502bd4beb172205ba4f9fba Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/android/java/AndroidManifest.xml | 16 ++++++++-------- src/android/java/res/values/libs.xml | 1 - src/android/java/res/values/strings.xml | 4 ---- 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/src/android/java/AndroidManifest.xml b/src/android/java/AndroidManifest.xml index 726801404a..937284fcd3 100644 --- a/src/android/java/AndroidManifest.xml +++ b/src/android/java/AndroidManifest.xml @@ -9,21 +9,21 @@ + - + - - + - - - - - + + + + + diff --git a/src/android/java/res/values/libs.xml b/src/android/java/res/values/libs.xml index c8e2fb9661..231406d224 100644 --- a/src/android/java/res/values/libs.xml +++ b/src/android/java/res/values/libs.xml @@ -3,7 +3,6 @@ https://download.qt-project.org/ministro/android/qt5/latest - default diff --git a/src/android/java/res/values/strings.xml b/src/android/java/res/values/strings.xml index 0b92c5542e..300f0673a4 100644 --- a/src/android/java/res/values/strings.xml +++ b/src/android/java/res/values/strings.xml @@ -1,10 +1,6 @@ - - - - Can\'t find Ministro service.\nThe application can\'t start. This application requires Ministro service. Would you like to install it? -- cgit v1.2.3 From 00962648008e9f6286fda5006af7287560bce456 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Tue, 15 Oct 2013 13:35:58 +0300 Subject: Fix deploy mechanism. The order of "android:value" and "android:name" attributes can be changed when saving the XML document. Use placeholders instead. Change-Id: I9a97bb0df2d2d16c8a9443a21ce7d3290e0ab466 Reviewed-by: Eskil Abrahamsen Blomfeldt Reviewed-by: Daniel Teske --- src/android/java/AndroidManifest.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/android/java/AndroidManifest.xml b/src/android/java/AndroidManifest.xml index 937284fcd3..6463793e0b 100644 --- a/src/android/java/AndroidManifest.xml +++ b/src/android/java/AndroidManifest.xml @@ -15,11 +15,11 @@ - + - + -- cgit v1.2.3 From a0a0b6446c1d6e436b72cdd986154ed6db8ca66e Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 21 Oct 2013 16:43:43 +0200 Subject: don't suggest to use qtAddModule(), it's internal API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Idf01d0dd74a0708014b7fca33611535c604a75f9 Reviewed-by: Joerg Bornemann Reviewed-by: Tor Arne Vestbø --- mkspecs/features/qt_functions.prf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkspecs/features/qt_functions.prf b/mkspecs/features/qt_functions.prf index 7bedf6f760..5a5f8a37b4 100644 --- a/mkspecs/features/qt_functions.prf +++ b/mkspecs/features/qt_functions.prf @@ -23,7 +23,7 @@ defineReplace(qtLibraryTarget) { } defineTest(qtAddLibrary) { - warning("qtAddLibrary() is deprecated. Use qtAddModule() or QT+= instead.") + warning("qtAddLibrary() is deprecated. Use QT+= instead.") # Reverse-engineer the module name from the library name. for(var, QT_MODULES) { -- cgit v1.2.3 From 7d462a2fb4391714e287161c5065196ec3cefbf1 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 21 Oct 2013 16:45:15 +0200 Subject: return()-related break() insanity is not necessary in qt5 Change-Id: I593c7160e44d51d25dee76c56c2e5580345ab42a Reviewed-by: Joerg Bornemann --- mkspecs/features/qt_functions.prf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkspecs/features/qt_functions.prf b/mkspecs/features/qt_functions.prf index 5a5f8a37b4..f1f7c00b9e 100644 --- a/mkspecs/features/qt_functions.prf +++ b/mkspecs/features/qt_functions.prf @@ -29,7 +29,7 @@ defineTest(qtAddLibrary) { for(var, QT_MODULES) { isEqual(QT.$${var}.name, $$1) { qtAddModule($$var, , LIBS) - return(true):break() # Yes, the break is insanity. But necessary. + return(true) } } error("No module matching library '$$1' found.") -- cgit v1.2.3 From f3785471b7f52a054d9f24e62e7dff905b4de75c Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 21 Oct 2013 22:07:00 +0200 Subject: de-duplicate QT_MODULES Change-Id: I8f1bf08070abb1ba05a4fdb14e7de9e7da5b3ec7 Reviewed-by: Joerg Bornemann --- mkspecs/features/qt_config.prf | 1 + 1 file changed, 1 insertion(+) diff --git a/mkspecs/features/qt_config.prf b/mkspecs/features/qt_config.prf index cbbd136270..208681d98a 100644 --- a/mkspecs/features/qt_config.prf +++ b/mkspecs/features/qt_config.prf @@ -29,6 +29,7 @@ QMAKE_QT_CONFIG = $$[QT_HOST_DATA/get]/mkspecs/qconfig.pri include($$mod) } } + QT_MODULES = $$unique(QT_MODULES) # In case modules appear in multiple places unset(QT_MODULE_INCLUDE_BASE) unset(QT_MODULE_LIB_BASE) unset(QT_MODULE_HOST_LIB_BASE) -- cgit v1.2.3 From 483a9d83f04b17b797df171d3eff91341a565a33 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Thu, 17 Oct 2013 16:48:02 +0300 Subject: Don't crash if the platform plugin is not initialized Change-Id: I999411816192edbd2bf40c6bda92d6e94fb3d1b0 Reviewed-by: Paul Olav Tvete --- src/plugins/platforms/android/src/androidjniinput.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/plugins/platforms/android/src/androidjniinput.cpp b/src/plugins/platforms/android/src/androidjniinput.cpp index 1e8a847159..30d4e69afe 100644 --- a/src/plugins/platforms/android/src/androidjniinput.cpp +++ b/src/plugins/platforms/android/src/androidjniinput.cpp @@ -228,6 +228,9 @@ namespace QtAndroidInput return; QAndroidPlatformIntegration *platformIntegration = QtAndroid::androidPlatformIntegration(); + if (!platformIntegration) + return; + QTouchDevice *touchDevice = platformIntegration->touchDevice(); if (touchDevice == 0) { touchDevice = new QTouchDevice; -- cgit v1.2.3 From 7e30d3afd35cd24b8888d6f392330c3afa69cb81 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Wed, 23 Oct 2013 12:22:58 +0200 Subject: QFileDialog can delete files too, not just directories After Ic12de12ec51c20de52d040514e90be5e783add43 this functionality was broken. Added an autotest. Task-number: QTBUG-34159 Change-Id: I8f41b7073dc57fea855ab87796f09e8a91520d13 Reviewed-by: David Faure --- src/widgets/dialogs/qfilesystemmodel.cpp | 2 ++ .../qfilesystemmodel/tst_qfilesystemmodel.cpp | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/widgets/dialogs/qfilesystemmodel.cpp b/src/widgets/dialogs/qfilesystemmodel.cpp index 6330d529fb..fa6306005b 100644 --- a/src/widgets/dialogs/qfilesystemmodel.cpp +++ b/src/widgets/dialogs/qfilesystemmodel.cpp @@ -204,6 +204,8 @@ bool QFileSystemModel::remove(const QModelIndex &aindex) #ifndef QT_NO_FILESYSTEMWATCHER d->fileInfoGatherer.removePath(path); #endif + if (QFileInfo(path).isFile()) + return QFile::remove(path); return QDir(path).removeRecursively(); } diff --git a/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp b/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp index 0b9fb5c168..61a2abc084 100644 --- a/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp +++ b/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp @@ -115,6 +115,7 @@ private slots: void sort(); void mkdir(); + void deleteFile(); void caseSensitivity(); @@ -927,6 +928,25 @@ void tst_QFileSystemModel::mkdir() QCOMPARE(oldRow, idx.row()); } +void tst_QFileSystemModel::deleteFile() +{ + QString newFilePath = QDir::temp().filePath("NewFileDeleteTest"); + QFile newFile(newFilePath); + if (newFile.exists()) { + if (!newFile.remove()) + qWarning() << "unable to remove" << newFilePath; + QTest::qWait(WAITTIME); + } + if (!newFile.open(QIODevice::WriteOnly | QIODevice::Text)) { + qWarning() << "unable to create" << newFilePath; + } + newFile.close(); + QModelIndex idx = model->index(newFilePath); + QVERIFY(idx.isValid()); + QVERIFY(model->remove(idx)); + QVERIFY(!newFile.exists()); +} + void tst_QFileSystemModel::caseSensitivity() { QString tmp = flatDirTestPath; -- cgit v1.2.3 From e55ecc4a5579adc3484560ac0b1c2513fec0d787 Mon Sep 17 00:00:00 2001 From: Venu Date: Tue, 22 Oct 2013 17:15:25 +0200 Subject: Doc: Added a link to the Qt Quick Test page Task-number: QTBUG-33316 Change-Id: Ib8c479837cac4b7cca47b979cbb2dad0aaae6412 Reviewed-by: Jerome Pasion Reviewed-by: Caroline Chao --- src/testlib/doc/src/qttest-index.qdoc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/testlib/doc/src/qttest-index.qdoc b/src/testlib/doc/src/qttest-index.qdoc index db42db1687..4cf0726429 100644 --- a/src/testlib/doc/src/qttest-index.qdoc +++ b/src/testlib/doc/src/qttest-index.qdoc @@ -56,6 +56,7 @@ \list \li \l{Qt Test C++ Classes}{C++ Classes} + \li \l{Qt Quick Test}{QML Types} \endlist */ -- cgit v1.2.3 From 17809b41a6232220b1b19052cd9ebf48899c476a Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Wed, 23 Oct 2013 15:25:11 +0200 Subject: Fix typo in check for MINGW_W64 version Got introduced in 9b187bcd6a256b53cc2fb85500 Change-Id: I1d713f8309d3d8568ea836cc1d29f9dca685ac01 Reviewed-by: Jonathan Liu Reviewed-by: Friedemann Kleint --- src/plugins/platforms/windows/qwindowsdialoghelpers.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp index 8c3b7e17c6..832ce24354 100644 --- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp +++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp @@ -1768,7 +1768,7 @@ static int CALLBACK xpFileDialogGetExistingDirCallbackProc(HWND hwnd, UINT uMsg, /* The correct declaration of the SHGetPathFromIDList symbol is * being used in mingw-w64 as of r6215, which is a v3 snapshot. */ -#if defined(Q_CC_MINGW) && (!defined(__MINGW64_VERSION_MAJOR) || _MINGW64_VERSION_MAJOR < 3) +#if defined(Q_CC_MINGW) && (!defined(__MINGW64_VERSION_MAJOR) || __MINGW64_VERSION_MAJOR < 3) typedef ITEMIDLIST *qt_LpItemIdList; #else typedef PIDLIST_ABSOLUTE qt_LpItemIdList; -- cgit v1.2.3 From 7c1b39705c3a3194e55da50f9f4d2e26d2e0bf32 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 16 Oct 2013 14:17:28 +0200 Subject: Fix crash in QXcbDrag. handleStatus() was called with drag==0 when releasing the mouse over the desktop. Task-number: QTBUG-33920 Change-Id: I553647d1e734934b7c6caf4c984683cff88f9162 Reviewed-by: Shawn Rutledge --- src/plugins/platforms/xcb/qxcbdrag.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp index 4961e0377c..d18693f6b8 100644 --- a/src/plugins/platforms/xcb/qxcbdrag.cpp +++ b/src/plugins/platforms/xcb/qxcbdrag.cpp @@ -835,7 +835,7 @@ void QXcbDrag::handle_xdnd_status(const xcb_client_message_event_t *event) void QXcbDrag::handleStatus(const xcb_client_message_event_t *event) { - if (event->window != connection()->clipboard()->owner()) + if (event->window != connection()->clipboard()->owner() || !drag()) return; xcb_client_message_event_t *lastEvent = const_cast(event); -- cgit v1.2.3 From d8745d249fdeaf40b0c8309c6922f034f794ae70 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 23 Oct 2013 15:41:27 +0200 Subject: Windows: Handle WM_SYSCOLORCHANGE as theme change. Task-number: QTBUG-34170 Change-Id: I6ca11ab67c1e2752300fc167fb8f3c4f0d9ae2b8 Reviewed-by: Joerg Bornemann --- src/plugins/platforms/windows/qtwindowsglobal.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/plugins/platforms/windows/qtwindowsglobal.h b/src/plugins/platforms/windows/qtwindowsglobal.h index ee5b6189b2..f6ed9447ef 100644 --- a/src/plugins/platforms/windows/qtwindowsglobal.h +++ b/src/plugins/platforms/windows/qtwindowsglobal.h @@ -204,6 +204,9 @@ inline QtWindows::WindowsEventType windowsEventType(UINT message, WPARAM wParamI case WM_DISPLAYCHANGE: return QtWindows::DisplayChangedEvent; case WM_THEMECHANGED: +#ifdef WM_SYSCOLORCHANGE // Windows 7: Handle color change as theme change (QTBUG-34170). + case WM_SYSCOLORCHANGE: +#endif return QtWindows::ThemeChanged; case WM_DWMCOMPOSITIONCHANGED: return QtWindows::CompositionSettingsChanged; -- cgit v1.2.3 From fe61f2d6b29cca87b46dc37c7968b2f765f670ef Mon Sep 17 00:00:00 2001 From: Wolfgang Bremer Date: Tue, 22 Oct 2013 16:18:11 +0200 Subject: Rename BlackBerry arm mkspecs to be aligned with NDK structure The current NDK uses CPUVARDIR variable to define whether x86 or armle-v7 is used. Therefore, the whole structure uses these two definitions to separate simulator and device builds. Renaming blackberry-armv7le-qcc to blackberry-armle-v7-qcc allows to directly use CPUVARDIR during Qt5 builds. For compatibility reasons the old folder is kept and includes the new qmake.conf. Change-Id: Ia7feeeabe16eda48140a65178af28cbb9bd085a9 Reviewed-by: Rafael Roquetto --- mkspecs/blackberry-armle-v7-qcc/qmake.conf | 22 ++++++++++++ mkspecs/blackberry-armle-v7-qcc/qplatformdefs.h | 42 ++++++++++++++++++++++ mkspecs/blackberry-armv7le-qcc/qmake.conf | 23 ++---------- mkspecs/blackberry-armv7le-qcc/qplatformdefs.h | 4 +-- .../blackberry-playbook-armle-v7-qcc/qmake.conf | 8 +++++ .../qplatformdefs.h | 42 ++++++++++++++++++++++ .../blackberry-playbook-armv7le-qcc/qmake.conf | 9 ++--- .../qplatformdefs.h | 2 +- 8 files changed, 123 insertions(+), 29 deletions(-) create mode 100644 mkspecs/blackberry-armle-v7-qcc/qmake.conf create mode 100644 mkspecs/blackberry-armle-v7-qcc/qplatformdefs.h create mode 100644 mkspecs/devices/blackberry-playbook-armle-v7-qcc/qmake.conf create mode 100644 mkspecs/devices/blackberry-playbook-armle-v7-qcc/qplatformdefs.h diff --git a/mkspecs/blackberry-armle-v7-qcc/qmake.conf b/mkspecs/blackberry-armle-v7-qcc/qmake.conf new file mode 100644 index 0000000000..2e24e4e0d3 --- /dev/null +++ b/mkspecs/blackberry-armle-v7-qcc/qmake.conf @@ -0,0 +1,22 @@ +# +# qmake configuration for blackberry armv7le systems +# + +load(qt_config) + +DEFINES += Q_OS_BLACKBERRY +CONFIG += blackberry +LIBS += -lbps + +# Blackberry also has support for stack smashing protection in its libc +contains(QT_CONFIG, stack-protector-strong) { + QMAKE_CFLAGS += -fstack-protector-strong +} else { + QMAKE_CFLAGS += -fstack-protector -fstack-protector-all +} + +QMAKE_CFLAGS += -mcpu=cortex-a9 -mtune=cortex-a9 -mthumb -D_FORTIFY_SOURCE=2 + +QMAKE_LFLAGS_SHLIB += -Wl,-z,relro -Wl,-z,now + +include(../common/qcc-base-qnx-armv7le.conf) diff --git a/mkspecs/blackberry-armle-v7-qcc/qplatformdefs.h b/mkspecs/blackberry-armle-v7-qcc/qplatformdefs.h new file mode 100644 index 0000000000..32becb2042 --- /dev/null +++ b/mkspecs/blackberry-armle-v7-qcc/qplatformdefs.h @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** Copyright (C) 2012 - 2013 BlackBerry Limited. All rights reserved. +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "../qnx-armv7le-qcc/qplatformdefs.h" diff --git a/mkspecs/blackberry-armv7le-qcc/qmake.conf b/mkspecs/blackberry-armv7le-qcc/qmake.conf index 2e24e4e0d3..ec462457c4 100644 --- a/mkspecs/blackberry-armv7le-qcc/qmake.conf +++ b/mkspecs/blackberry-armv7le-qcc/qmake.conf @@ -1,22 +1,5 @@ # -# qmake configuration for blackberry armv7le systems +# deprecated, please use blackberry-armle-v7-qcc instead # - -load(qt_config) - -DEFINES += Q_OS_BLACKBERRY -CONFIG += blackberry -LIBS += -lbps - -# Blackberry also has support for stack smashing protection in its libc -contains(QT_CONFIG, stack-protector-strong) { - QMAKE_CFLAGS += -fstack-protector-strong -} else { - QMAKE_CFLAGS += -fstack-protector -fstack-protector-all -} - -QMAKE_CFLAGS += -mcpu=cortex-a9 -mtune=cortex-a9 -mthumb -D_FORTIFY_SOURCE=2 - -QMAKE_LFLAGS_SHLIB += -Wl,-z,relro -Wl,-z,now - -include(../common/qcc-base-qnx-armv7le.conf) +warning("You are using deprecated mkspecs. Please use blackberry-armle-v7-qcc instead.") +include(../blackberry-armle-v7-qcc/qmake.conf) diff --git a/mkspecs/blackberry-armv7le-qcc/qplatformdefs.h b/mkspecs/blackberry-armv7le-qcc/qplatformdefs.h index b15869f163..a3e7b16ef7 100644 --- a/mkspecs/blackberry-armv7le-qcc/qplatformdefs.h +++ b/mkspecs/blackberry-armv7le-qcc/qplatformdefs.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2012 Research In Motion Limited. +** Copyright (C) 2012 - 2013 BlackBerry Limited. All rights reserved. ** Contact: http://www.qt-project.org/legal ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -39,4 +39,4 @@ ** ****************************************************************************/ -#include "../qnx-armv7le-qcc/qplatformdefs.h" +#include "../blackberry-armle-v7-qcc/qplatformdefs.h" diff --git a/mkspecs/devices/blackberry-playbook-armle-v7-qcc/qmake.conf b/mkspecs/devices/blackberry-playbook-armle-v7-qcc/qmake.conf new file mode 100644 index 0000000000..c9c883a206 --- /dev/null +++ b/mkspecs/devices/blackberry-playbook-armle-v7-qcc/qmake.conf @@ -0,0 +1,8 @@ +# +# qmake configuration for the Blackberry Playbook armv7le +# + +include(../../blackberry-armle-v7-qcc/qmake.conf) + +DEFINES += Q_OS_BLACKBERRY_TABLET +CONFIG += blackberry-playbook diff --git a/mkspecs/devices/blackberry-playbook-armle-v7-qcc/qplatformdefs.h b/mkspecs/devices/blackberry-playbook-armle-v7-qcc/qplatformdefs.h new file mode 100644 index 0000000000..a78e441501 --- /dev/null +++ b/mkspecs/devices/blackberry-playbook-armle-v7-qcc/qplatformdefs.h @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Klarälvdalens Datakonsult AB +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "../../blackberry-armle-v7-qcc/qplatformdefs.h" diff --git a/mkspecs/devices/blackberry-playbook-armv7le-qcc/qmake.conf b/mkspecs/devices/blackberry-playbook-armv7le-qcc/qmake.conf index cc7435d1dc..1b3299659f 100644 --- a/mkspecs/devices/blackberry-playbook-armv7le-qcc/qmake.conf +++ b/mkspecs/devices/blackberry-playbook-armv7le-qcc/qmake.conf @@ -1,8 +1,5 @@ # -# qmake configuration for the Blackberry Playbook armv7le +# deprecated, please use blackberry-playbook-armle-v7-qcc instead # - -include(../../blackberry-armv7le-qcc/qmake.conf) - -DEFINES += Q_OS_BLACKBERRY_TABLET -CONFIG += blackberry-playbook +warning("You are using deprecated mkspecs. Please use blackberry-playbook-armle-v7-qcc instead.") +include(../blackberry-playbook-armle-v7-qcc/qmake.conf) diff --git a/mkspecs/devices/blackberry-playbook-armv7le-qcc/qplatformdefs.h b/mkspecs/devices/blackberry-playbook-armv7le-qcc/qplatformdefs.h index 127ca957dd..61cd7119cc 100644 --- a/mkspecs/devices/blackberry-playbook-armv7le-qcc/qplatformdefs.h +++ b/mkspecs/devices/blackberry-playbook-armv7le-qcc/qplatformdefs.h @@ -39,4 +39,4 @@ ** ****************************************************************************/ -#include "../../blackberry-armv7le-qcc/qplatformdefs.h" +#include "../blackberry-playbook-armle-v7-qcc/qplatformdefs.h" -- cgit v1.2.3 From 5cc76dae7e985a7a39d839524dc8ad6475e597f3 Mon Sep 17 00:00:00 2001 From: Jonathan Hoffmann Date: Fri, 13 Sep 2013 14:05:35 -0400 Subject: BlackBerry: improve BPS event lifetime management In QEventDispatcherBlackberry::select(), if an event handler called through filterEvent() starts a nested event loop by creating a new QEventLoop, we will recursively enter the select() method again. However, each time bps_get_event() is called, it destroys the last event it handed out before returning the next event. We don't want it to destroy the event that triggered the nested event loop, since there may still be more handlers that need to get that event, once the nested event loop is done and control returns to the outer event loop. So we move an event to a holding channel, which takes ownership of the event. Putting the event on our own channel allows us to manage when it is destroyed, keeping it alive until we know we are done with it. Each recursive call of this function needs to have it's own holding channel, since a channel is a queue, not a stack. However, a recursive call into the select() method happens very rarely compared to the many times this method is called. We don't want to create a holding channel for each time this method is called, only when it is called recursively. Thus we have the instance variable d->holding_channel to use in the common case. We keep track of recursive calls with d->loop_level. If we are in a recursive call, then we create a new holding channel for this run. Change-Id: Ib3584676d2db5a9a3754a1535d5fb6c9e14f5dbb Reviewed-by: Thomas McGuire --- src/corelib/kernel/qeventdispatcher_blackberry.cpp | 90 +++++++++++++++++++++- src/corelib/kernel/qeventdispatcher_blackberry_p.h | 4 +- 2 files changed, 90 insertions(+), 4 deletions(-) diff --git a/src/corelib/kernel/qeventdispatcher_blackberry.cpp b/src/corelib/kernel/qeventdispatcher_blackberry.cpp index d9e38b68b2..b9137ec139 100644 --- a/src/corelib/kernel/qeventdispatcher_blackberry.cpp +++ b/src/corelib/kernel/qeventdispatcher_blackberry.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2012 Research In Motion +** Copyright (C) 2012 - 2013 BlackBerry Limited. All rights reserved. ** Contact: http://www.qt-project.org/legal ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -78,6 +78,19 @@ private: int outerChannel; }; +class BBScopedLoopLevelCounter +{ + QEventDispatcherBlackberryPrivate *d; + +public: + inline BBScopedLoopLevelCounter(QEventDispatcherBlackberryPrivate *p) + : d(p) + { ++d->loop_level; } + + inline ~BBScopedLoopLevelCounter() + { --d->loop_level; } +}; + struct bpsIOHandlerData { bpsIOHandlerData() @@ -147,7 +160,8 @@ static int bpsIOHandler(int fd, int io_events, void *data) } QEventDispatcherBlackberryPrivate::QEventDispatcherBlackberryPrivate() - : ioData(new bpsIOHandlerData) + : loop_level(0) + , ioData(new bpsIOHandlerData) { // prepare to use BPS int result = bps_initialize(); @@ -156,6 +170,11 @@ QEventDispatcherBlackberryPrivate::QEventDispatcherBlackberryPrivate() bps_channel = bps_channel_get_active(); + if (bps_channel_create(&holding_channel, 0) != BPS_SUCCESS) { + qWarning("QEventDispatcherBlackberry: bps_channel_create failed"); + holding_channel = -1; + } + // get domain for IO ready and wake up events - ignoring race condition here for now if (bpsUnblockDomain == -1) { bpsUnblockDomain = bps_register_domain(); @@ -166,6 +185,11 @@ QEventDispatcherBlackberryPrivate::QEventDispatcherBlackberryPrivate() QEventDispatcherBlackberryPrivate::~QEventDispatcherBlackberryPrivate() { + if ((holding_channel != -1) && + (bps_channel_destroy(holding_channel) != BPS_SUCCESS)) { + qWarning("QEventDispatcherBlackberry: bps_channel_destroy failed"); + } + // we're done using BPS bps_shutdown(); } @@ -280,11 +304,21 @@ static inline int timespecToMillisecs(const timespec &tv) return (tv.tv_sec * 1000) + (tv.tv_nsec / 1000000); } +static inline void destroyHeldBpsEvent(int holding_channel) +{ + // Switch to the holding channel and use bps_get_event() to trigger its destruction. We + // don't care about the return value from this call to bps_get_event(). + BpsChannelScopeSwitcher holdingChannelSwitcher(holding_channel); + bps_event_t *held_event = 0; + (void)bps_get_event(&held_event, 0); + } + int QEventDispatcherBlackberry::select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, timespec *timeout) { Q_UNUSED(nfds); Q_D(QEventDispatcherBlackberry); + const BBScopedLoopLevelCounter bbLoopCounter(d); BpsChannelScopeSwitcher channelSwitcher(d->bps_channel); @@ -307,6 +341,31 @@ int QEventDispatcherBlackberry::select(int nfds, fd_set *readfds, fd_set *writef bps_event_t *event = 0; unsigned int eventCount = 0; + // If an event handler called through filterEvent() starts a nested event loop by creating a + // new QEventLoop, we will recursively enter this function again. However, each time + // bps_get_event() is called, it destroys the last event it handed out before returning the + // next event. We don't want it to destroy the event that triggered the nested event loop, + // since there may still be more handlers that need to get that event, once the nested event + // loop is done and control returns to the outer event loop. + // + // So we move an event to a holding channel, which takes ownership of the event. Putting + // the event on our own channel allows us to manage when it is destroyed, keeping it alive + // until we know we are done with it. Each recursive call of this function needs to have + // it's own holding channel, since a channel is a queue, not a stack. + // + // However, a recursive call into this function happens very rarely compared to the many + // times this function is called. We don't want to create a holding channel for each time + // this function is called, only when it is called recursively. Thus we have the instance + // variable d->holding_channel to use in the common case. We keep track of recursive calls + // with d->loop_level. If we are in a recursive call, then we create a new holding channel + // for this run. + int holding_channel = d->holding_channel; + if ((d->loop_level > 1) && + Q_UNLIKELY(bps_channel_create(&holding_channel, 0) != BPS_SUCCESS)) { + qWarning("QEventDispatcherBlackberry: bps_channel_create failed"); + holding_channel = -1; + } + // Convert timeout to milliseconds int timeoutTotal = -1; if (timeout) @@ -331,6 +390,11 @@ int QEventDispatcherBlackberry::select(int nfds, fd_set *readfds, fd_set *writef emit awake(); filterNativeEvent(QByteArrayLiteral("bps_event_t"), static_cast(event), 0); emit aboutToBlock(); + + if (Q_LIKELY(holding_channel != -1)) { + // We are now done with this BPS event. Destroy it. + destroyHeldBpsEvent(holding_channel); + } } // Update the timeout @@ -370,6 +434,12 @@ int QEventDispatcherBlackberry::select(int nfds, fd_set *readfds, fd_set *writef if (bps_event_get_domain(event) == bpsUnblockDomain) { timeoutTotal = 0; // in order to immediately drain the event queue of native events event = 0; // (especially touch move events) we don't break out here + } else { + // Move the event to our holding channel so we can manage when it is destroyed. + if (Q_LIKELY(holding_channel != 1) && + Q_UNLIKELY(bps_channel_push_event(holding_channel, event) != BPS_SUCCESS)) { + qWarning("QEventDispatcherBlackberry: bps_channel_push_event failed"); + } } ++eventCount; @@ -379,12 +449,26 @@ int QEventDispatcherBlackberry::select(int nfds, fd_set *readfds, fd_set *writef const unsigned int maximumEventCount = 12; if (Q_UNLIKELY((eventCount > maximumEventCount && timeoutLeft == 0) || !QElapsedTimer::isMonotonic())) { - if (event) + if (event) { filterNativeEvent(QByteArrayLiteral("bps_event_t"), static_cast(event), 0); + + if (Q_LIKELY(holding_channel != -1)) { + // We are now done with this BPS event. Destroy it. + destroyHeldBpsEvent(holding_channel); + } + } break; } } + // If this was a recursive call into this function, a new holding channel was created for + // this run, so destroy it now. + if ((holding_channel != d->holding_channel) && + Q_LIKELY(holding_channel != -1) && + Q_UNLIKELY(bps_channel_destroy(holding_channel) != BPS_SUCCESS)) { + qWarning("QEventDispatcherBlackberry: bps_channel_destroy failed"); + } + // the number of bits set in the file sets return d->ioData->count; } diff --git a/src/corelib/kernel/qeventdispatcher_blackberry_p.h b/src/corelib/kernel/qeventdispatcher_blackberry_p.h index 5a4c3a9dcd..1764c244d8 100644 --- a/src/corelib/kernel/qeventdispatcher_blackberry_p.h +++ b/src/corelib/kernel/qeventdispatcher_blackberry_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2012 Research In Motion +** Copyright (C) 2012 - 2013 BlackBerry Limited. All rights reserved. ** Contact: http://www.qt-project.org/legal ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -95,6 +95,8 @@ public: int processThreadWakeUp(int nsel); int bps_channel; + int holding_channel; + int loop_level; QScopedPointer ioData; }; -- cgit v1.2.3 From 6d3e821349944229d02c878edc38b1781c567350 Mon Sep 17 00:00:00 2001 From: Sean Harmer Date: Wed, 23 Oct 2013 11:54:36 +0100 Subject: Remove doc references to non-existing functions in QSurfaceFormat Change-Id: I5a9de5b719e111e47a1ea7334609695f1db6149a Reviewed-by: Jerome Pasion Reviewed-by: Gunnar Sletta --- src/gui/kernel/qsurfaceformat.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/kernel/qsurfaceformat.cpp b/src/gui/kernel/qsurfaceformat.cpp index b2abed7812..2f1b30ae4a 100644 --- a/src/gui/kernel/qsurfaceformat.cpp +++ b/src/gui/kernel/qsurfaceformat.cpp @@ -337,7 +337,7 @@ bool QSurfaceFormat::testOption(QSurfaceFormat::FormatOptions opt) const /*! Set the minimum depth buffer size to \a size. - \sa depthBufferSize(), setDepth(), depth() + \sa depthBufferSize() */ void QSurfaceFormat::setDepthBufferSize(int size) { @@ -350,7 +350,7 @@ void QSurfaceFormat::setDepthBufferSize(int size) /*! Returns the depth buffer size. - \sa setDepthBufferSize(), setDepth(), depth() + \sa setDepthBufferSize() */ int QSurfaceFormat::depthBufferSize() const { -- cgit v1.2.3 From 2e3870fe37d36ccf4bd84eb90e1d5e08ad00c1bc Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Wed, 9 Oct 2013 14:19:53 +0200 Subject: Reserve some space for future use in QLoggingCategory Currently Qt offers only debug, warning, critical message types for general use. Most logging frameworks offer more ... let's save some space for future message types. Change-Id: Icb4333da5c8f5277fd10d8a01b06d95369662bdc Reviewed-by: Thiago Macieira --- src/corelib/io/qloggingcategory.cpp | 5 ++++- src/corelib/io/qloggingcategory.h | 4 ++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qloggingcategory.cpp b/src/corelib/io/qloggingcategory.cpp index d472682ace..8d337ec630 100644 --- a/src/corelib/io/qloggingcategory.cpp +++ b/src/corelib/io/qloggingcategory.cpp @@ -123,7 +123,10 @@ QLoggingCategory::QLoggingCategory(const char *category) enabledDebug(false), enabledWarning(true), enabledCritical(true), - enabledTrace(false) + enabledTrace(false), + placeholder1(false), + placeholder2(false), + placeholder3(false) { bool isDefaultCategory = (category == 0) || (strcmp(category, qtDefaultCategoryName) == 0); diff --git a/src/corelib/io/qloggingcategory.h b/src/corelib/io/qloggingcategory.h index 6009226127..7a119f4937 100644 --- a/src/corelib/io/qloggingcategory.h +++ b/src/corelib/io/qloggingcategory.h @@ -92,6 +92,10 @@ private: bool enabledWarning; bool enabledCritical; bool enabledTrace; + // reserve space for future use + bool placeholder1; + bool placeholder2; + bool placeholder3; }; class Q_CORE_EXPORT QTracer -- cgit v1.2.3