From 38f6467b818cff995e08630037b8b0c46e20ec43 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Mon, 22 Apr 2013 13:18:57 +0200 Subject: ANGLE: Fix compilation with MinGW Make sure ImageSSE2.cpp is compiled with the right flags (-msse2) Change-Id: I410bbd1fd78112d01ebd486908cd22d827e2e472 Reviewed-by: Jonathan Liu Reviewed-by: Friedemann Kleint --- src/angle/src/libGLESv2/libGLESv2.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/angle/src/libGLESv2/libGLESv2.pro b/src/angle/src/libGLESv2/libGLESv2.pro index 681cd1be19..d12202f33b 100644 --- a/src/angle/src/libGLESv2/libGLESv2.pro +++ b/src/angle/src/libGLESv2/libGLESv2.pro @@ -87,7 +87,7 @@ SOURCES += \ $$ANGLE_DIR/src/libGLESv2/renderer/VertexBuffer.cpp \ $$ANGLE_DIR/src/libGLESv2/renderer/VertexDataManager.cpp -sse2:SOURCES += $$ANGLE_DIR/src/libGLESv2/renderer/ImageSSE2.cpp +SSE2_SOURCES += $$ANGLE_DIR/src/libGLESv2/renderer/ImageSSE2.cpp angle_d3d11 { HEADERS += \ -- cgit v1.2.3 From 8a00a42d0dc902153dd1f12981f2a8980cfd4272 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 19 Apr 2013 10:48:37 +0200 Subject: iOS: don't delete m_touchDevice, QPA takes ownership MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When registering m_touchDevice with QWindowSystemInterface, it will also transfer ownership to it. It will eventually be deleted in clenupDevicesList on qtouchdevice.cpp. This patch will also stop the app from crashing when telling it to quit. Change-Id: I97070efdf16b4db7d076935fbec62e60f094a7df Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosintegration.h | 1 - src/plugins/platforms/ios/qiosintegration.mm | 5 ----- 2 files changed, 6 deletions(-) diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h index 329a0a3d9b..c352e0f2d2 100644 --- a/src/plugins/platforms/ios/qiosintegration.h +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -52,7 +52,6 @@ class QIOSIntegration : public QPlatformIntegration, public QPlatformNativeInter { public: QIOSIntegration(); - ~QIOSIntegration(); bool hasCapability(Capability cap) const; diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index c7541c3e38..61fd1c3d60 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -79,11 +79,6 @@ QIOSIntegration::QIOSIntegration() QWindowSystemInterface::registerTouchDevice(m_touchDevice); } -QIOSIntegration::~QIOSIntegration() -{ - delete m_touchDevice; -} - bool QIOSIntegration::hasCapability(Capability cap) const { switch (cap) { -- cgit v1.2.3 From 353f7340a18b06e92851ee199a4c65672595cb7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Mon, 22 Apr 2013 14:41:37 +0200 Subject: Revert "Don't warn on 0x0 sized windows." MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 88272d6c04f0f67fa9612dc7bdb2a5f8ba8d0314, which accidentally re-introduced a crash. Change-Id: Ie60bcf55f940b24f982eed4f20c6af3320b040a7 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/cocoa/qcocoawindow.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 5ff1bf83ae..e726c1e4fd 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -863,7 +863,7 @@ void QCocoaWindow::syncWindowState(Qt::WindowState newState) // if content view width or height is 0 then the window animations will crash so // do nothing except set the new state NSRect contentRect = [contentView() frame]; - if (contentRect.size.width < 0 || contentRect.size.height < 0) { + if (contentRect.size.width <= 0 || contentRect.size.height <= 0) { qWarning() << Q_FUNC_INFO << "invalid window content view size, check your window geometry"; m_synchedWindowState = newState; return; -- cgit v1.2.3 From d64274d4ffd0556e3de6da82cb8220ebba2d9186 Mon Sep 17 00:00:00 2001 From: Sergio Ahumada Date: Fri, 19 Apr 2013 15:57:45 +0200 Subject: test: Disable tst_uic when -no-widgets is used uic doesn't get compiled when -no-widgets is used, so disabling its test. Change-Id: I8c81ec468e40841548dacb356fd87ecf85d7b6ac Reviewed-by: Oswald Buddenhagen --- tests/auto/tools/tools.pro | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/auto/tools/tools.pro b/tests/auto/tools/tools.pro index 9b4d2ca22a..5367e8b7ef 100644 --- a/tests/auto/tools/tools.pro +++ b/tests/auto/tools/tools.pro @@ -6,3 +6,4 @@ SUBDIRS=\ rcc \ qtHaveModule(dbus): SUBDIRS += qdbuscpp2xml qdbusxml2cpp +!qtHaveModule(widgets): SUBDIRS -= uic -- cgit v1.2.3 From 241ee2ee4208eb6b338390f82b71f1b1d7c4c5b0 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Wed, 17 Apr 2013 12:44:36 +0200 Subject: Read correct font hinting config on Gnome/Unity Fixes regression against Qt 4. This tries to recreate the logic from 5c46d9a4c85abbcc0b5db2bbbafded3efd784cd9 in Qt 4, where we on Gnome would override the default hint style specified in FontConfig with Xft.hintstyle settings. This is the configuration used for changing the hint style in the Gnome Tweak Tool. Task-number: QTBUG-29582 Change-Id: I6b9fe2c8ff55ff080d034e5a53fc8cbb49f7651f Reviewed-by: Konstantin Ritt Reviewed-by: Paul Olav Tvete --- .../fontconfig/qfontconfigdatabase.cpp | 19 ++++++++++ src/plugins/platforms/xcb/qxcbnativeinterface.cpp | 3 ++ src/plugins/platforms/xcb/qxcbnativeinterface.h | 3 +- src/plugins/platforms/xcb/qxcbscreen.cpp | 42 ++++++++++++++++++---- src/plugins/platforms/xcb/qxcbscreen.h | 9 +++++ 5 files changed, 68 insertions(+), 8 deletions(-) diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp index 9c28c9fa63..91472f9efb 100644 --- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp +++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp @@ -47,11 +47,17 @@ #include +#include #include +#include +#include #include #include #include +#include + +#include #include #include FT_TRUETYPE_TABLES_H @@ -640,6 +646,19 @@ QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, QChar::Script sc break; } } + + if (f.hintingPreference == QFont::PreferDefaultHinting) { + QByteArray desktopEnvironment = QGuiApplicationPrivate::platformIntegration()->services()->desktopEnvironment(); + if (desktopEnvironment == "GNOME" || desktopEnvironment == "UNITY") { + void *hintStyleResource = + QGuiApplication::platformNativeInterface()->nativeResourceForScreen("hintstyle", + QGuiApplication::primaryScreen()); + int hintStyle = int(reinterpret_cast(hintStyleResource)); + if (hintStyle > 0) + default_hint_style = QFontEngine::HintStyle(hintStyle - 1); + } + } + engine->setDefaultHintStyle(default_hint_style); if (antialias) { diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp index 6241898462..6ac69a8335 100644 --- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp +++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp @@ -77,6 +77,7 @@ public: insert("glxcontext",QXcbNativeInterface::GLXContext); insert("apptime",QXcbNativeInterface::AppTime); insert("appusertime",QXcbNativeInterface::AppUserTime); + insert("hintstyle", QXcbNativeInterface::ScreenHintStyle); } }; @@ -139,6 +140,8 @@ void *QXcbNativeInterface::nativeResourceForScreen(const QByteArray &resource, Q case AppUserTime: result = appUserTime(xcbScreen); break; + case ScreenHintStyle: + result = reinterpret_cast(xcbScreen->hintStyle() + 1); default: break; } diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.h b/src/plugins/platforms/xcb/qxcbnativeinterface.h index db0fa3e2ca..919a21d00d 100644 --- a/src/plugins/platforms/xcb/qxcbnativeinterface.h +++ b/src/plugins/platforms/xcb/qxcbnativeinterface.h @@ -64,7 +64,8 @@ public: EglContext, GLXContext, AppTime, - AppUserTime + AppUserTime, + ScreenHintStyle }; QXcbNativeInterface(); diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp index 7ae4e19dc3..38b4c873ad 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.cpp +++ b/src/plugins/platforms/xcb/qxcbscreen.cpp @@ -67,6 +67,7 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *scr, , m_number(number) , m_refreshRate(60) , m_forcedDpi(-1) + , m_hintStyle(QFontEngine::HintStyle(-1)) { if (connection->hasXRandr()) xcb_randr_select_input(xcb_connection(), screen()->root, true); @@ -481,6 +482,35 @@ QPixmap QXcbScreen::grabWindow(WId window, int x, int y, int width, int height) return result; } +bool QXcbScreen::xResource(const QByteArray &identifier, + const QByteArray &expectedIdentifier, + int *value) +{ + Q_ASSERT(value != 0); + if (identifier.startsWith(expectedIdentifier)) { + QByteArray stringValue = identifier.mid(expectedIdentifier.size()); + + bool ok; + *value = stringValue.toInt(&ok); + if (!ok) { + if (stringValue == "hintfull") + *value = QFontEngine::HintFull; + else if (stringValue == "hintnone") + *value = QFontEngine::HintNone; + else if (stringValue == "hintmedium") + *value = QFontEngine::HintMedium; + else if (stringValue == "hintslight") + *value = QFontEngine::HintLight; + + return *value != 0; + } + + return true; + } + + return false; +} + void QXcbScreen::readXResources() { int offset = 0; @@ -508,13 +538,11 @@ void QXcbScreen::readXResources() QList split = resources.split('\n'); for (int i = 0; i < split.size(); ++i) { const QByteArray &r = split.at(i); - if (r.startsWith("Xft.dpi:\t")) { - bool ok; - int dpi = r.mid(sizeof("Xft.dpi:")).toInt(&ok); - if (ok) - m_forcedDpi = dpi; - break; - } + int value; + if (xResource(r, "Xft.dpi:\t", &value)) + m_forcedDpi = value; + else if (xResource(r, "Xft.hintstyle:\t", &value)) + m_hintStyle = QFontEngine::HintStyle(value); } } diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h index 4c7d7f2c1c..c3b13fd1ea 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.h +++ b/src/plugins/platforms/xcb/qxcbscreen.h @@ -50,6 +50,8 @@ #include "qxcbobject.h" +#include + QT_BEGIN_NAMESPACE class QXcbConnection; @@ -97,7 +99,13 @@ public: void updateRefreshRate(); void readXResources(); + + QFontEngine::HintStyle hintStyle() const { return m_hintStyle; } private: + static bool xResource(const QByteArray &identifier, + const QByteArray &expectedIdentifier, + int *value); + xcb_screen_t *m_screen; xcb_randr_crtc_t m_crtc; QString m_outputName; @@ -116,6 +124,7 @@ private: QXcbCursor *m_cursor; int m_refreshRate; int m_forcedDpi; + QFontEngine::HintStyle m_hintStyle; }; QT_END_NAMESPACE -- cgit v1.2.3 From 00b11ccdead05d77589d4ec5ebb3b376c6ae2ca1 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Tue, 16 Apr 2013 17:40:59 +0200 Subject: Fix QTableView::doItemsLayout() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Keep the content aligned to the bottom when the view has been scrolled to the bottom and the content is relayouted (for example due to sorting). Task-number: QTBUG-30653 Change-Id: I9513e295e276d25ff2068036cd80dbf91314fe84 Reviewed-by: Thorbjørn Lund Martsum Reviewed-by: Stephen Kelly --- src/widgets/itemviews/qtableview.cpp | 11 +++++-- .../itemviews/qtableview/tst_qtableview.cpp | 34 ++++++++++++++++++++++ 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/widgets/itemviews/qtableview.cpp b/src/widgets/itemviews/qtableview.cpp index 38e4a0bf9b..a6623b9462 100644 --- a/src/widgets/itemviews/qtableview.cpp +++ b/src/widgets/itemviews/qtableview.cpp @@ -1113,10 +1113,15 @@ void QTableView::doItemsLayout() { Q_D(QTableView); QAbstractItemView::doItemsLayout(); - if (verticalScrollMode() == QAbstractItemView::ScrollPerItem) - d->verticalHeader->setOffsetToSectionPosition(verticalScrollBar()->value()); - else + if (verticalScrollMode() == QAbstractItemView::ScrollPerItem) { + const int max = verticalScrollBar()->maximum(); + if (max > 0 && verticalScrollBar()->value() == max) + d->verticalHeader->setOffsetToLastSection(); + else + d->verticalHeader->setOffsetToSectionPosition(verticalScrollBar()->value()); + } else { d->verticalHeader->setOffset(verticalScrollBar()->value()); + } if (!d->verticalHeader->updatesEnabled()) d->verticalHeader->setUpdatesEnabled(true); } diff --git a/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp b/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp index 13476a7ffa..8e888f06ee 100644 --- a/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp +++ b/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp @@ -199,6 +199,7 @@ private slots: void taskQTBUG_7774_RtoLVisualRegionForSelection(); void taskQTBUG_8777_scrollToSpans(); void taskQTBUG_10169_sizeHintForRow(); + void taskQTBUG_30653_doItemsLayout(); void mouseWheel_data(); void mouseWheel(); @@ -4096,5 +4097,38 @@ void tst_QTableView::viewOptions() QVERIFY(options.showDecorationSelected); } +void tst_QTableView::taskQTBUG_30653_doItemsLayout() +{ + QWidget topLevel; + QtTestTableView view(&topLevel); + + QtTestTableModel model(5, 5); + view.setModel(&model); + + QtTestItemDelegate delegate; + delegate.hint = QSize(50, 50); + view.setItemDelegate(&delegate); + + view.resizeRowsToContents(); + view.resizeColumnsToContents(); + + // show two and half rows/cols + int extraWidth = view.verticalHeader()->sizeHint().width() + view.verticalScrollBar()->sizeHint().width(); + int extraHeight = view.horizontalHeader()->sizeHint().height() + view.horizontalScrollBar()->sizeHint().height(); + view.resize(125 + extraWidth, 125 + extraHeight); + + topLevel.show(); + QVERIFY(QTest::qWaitForWindowExposed(&topLevel)); + + // the offset after scrollToBottom() and doItemsLayout() should not differ + // as the view content should stay aligned to the last section + view.scrollToBottom(); + int scrollToBottomOffset = view.verticalHeader()->offset(); + view.doItemsLayout(); + int doItemsLayoutOffset = view.verticalHeader()->offset(); + + QCOMPARE(scrollToBottomOffset, doItemsLayoutOffset); +} + QTEST_MAIN(tst_QTableView) #include "tst_qtableview.moc" -- cgit v1.2.3 From d257e69a791b97a0646eb7c5a798dc3fe3db456f Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Wed, 3 Apr 2013 21:33:16 +0200 Subject: Accessibility Mac: Implement accessibilityFocusedUIElement MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I17b5b1f741a8b340d8f4b16f4ec39cc9a8159bfa Reviewed-by: Morten Johan Sørvig Reviewed-by: Jan Arve Sæther --- src/plugins/platforms/cocoa/qnsviewaccessibility.mm | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/plugins/platforms/cocoa/qnsviewaccessibility.mm b/src/plugins/platforms/cocoa/qnsviewaccessibility.mm index c43c0b5068..6ebb1f6ba8 100644 --- a/src/plugins/platforms/cocoa/qnsviewaccessibility.mm +++ b/src/plugins/platforms/cocoa/qnsviewaccessibility.mm @@ -106,9 +106,27 @@ // Hit a child, forward to child accessible interface. QAccessible::Id childAxid = QAccessible::uniqueId(childInterface); + // FIXME: parent could be wrong QCocoaAccessibleElement *accessibleElement = [QCocoaAccessibleElement createElementWithId:childAxid parent:self ]; [accessibleElement autorelease]; return [accessibleElement accessibilityHitTest:point]; } +- (id)accessibilityFocusedUIElement { + if (!m_window->accessibleRoot()) + return [super accessibilityFocusedUIElement]; + + QAccessibleInterface *childInterface = m_window->accessibleRoot()->focusChild(); + if (childInterface) { + QAccessible::Id childAxid = QAccessible::uniqueId(childInterface); + // FIXME: parent could be wrong + QCocoaAccessibleElement *accessibleElement = [QCocoaAccessibleElement createElementWithId:childAxid parent:self]; + [accessibleElement autorelease]; + return accessibleElement; + } + + // should not happen + return nil; +} + @end -- cgit v1.2.3 From bc4fbcd215b72951d37db57103365963f3849fbc Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Tue, 16 Apr 2013 13:38:19 +0200 Subject: Add IMPORTED targets for the GL libraries used by Qt. There may be multiple libraries specified in the mkspec, such as EGL and Mali, as used in devices/linux-sh4-stmicro-ST7108-g++, so create an imported target for each one. Also populate the Qt5Gui_EGL_LIBS variable with all created imported targets. Similar variables are created for the used OPENGL implementation. In the case of using the packaged ANGLE library, we already know the exact locations of the binaries. This makes it possible for third parties to use the same GL implementation as used by the Qt build itself. As these are used only privately by QtGui, they are also added to the DEPENDENT_LIBRARIES of that target so that they are found for rpath-link usage. On some platforms (eg Raspberry Pi), multiple include directories must be set to include egl.h, as the headers it includes for vcos are a bit scattered. Task-number: QTBUG-29132 Change-Id: I1126da3d37cd51c88d3670347c8b6405b285efb5 Reviewed-by: Volker Krause Reviewed-by: Stephen Kelly --- mkspecs/features/cmake_functions.prf | 23 +++++ mkspecs/features/ctest_testcase.prf | 3 + src/gui/Qt5GuiConfigExtras.cmake.in | 109 +++++++++++++++++++++++- src/gui/gui.pro | 39 ++++++++- tests/auto/cmake/CMakeLists.txt | 6 ++ tests/auto/cmake/test_egl_lib/CMakeLists.txt | 14 +++ tests/auto/cmake/test_egl_lib/main.cpp | 48 +++++++++++ tests/auto/cmake/test_opengl_lib/CMakeLists.txt | 24 ++++++ tests/auto/cmake/test_opengl_lib/main.cpp | 65 ++++++++++++++ 9 files changed, 326 insertions(+), 5 deletions(-) create mode 100644 tests/auto/cmake/test_egl_lib/CMakeLists.txt create mode 100644 tests/auto/cmake/test_egl_lib/main.cpp create mode 100644 tests/auto/cmake/test_opengl_lib/CMakeLists.txt create mode 100644 tests/auto/cmake/test_opengl_lib/main.cpp diff --git a/mkspecs/features/cmake_functions.prf b/mkspecs/features/cmake_functions.prf index 1285990206..1e7c0e23f7 100644 --- a/mkspecs/features/cmake_functions.prf +++ b/mkspecs/features/cmake_functions.prf @@ -40,3 +40,26 @@ defineReplace(cmakeTargetPaths) { } return ($$join(out, " ")) } + +defineReplace(cmakePortablePaths) { + variable = $$1 + out = + for(v, variable) { + out += ${CMAKE_FIND_ROOT_PATH}$$cmakeTargetPath($$v) + } + return ($$join(out, " ")) +} + +defineReplace(cmakeProcessLibs) { + variable = $$1 + out = + for(v, variable) { + if(!equals(v, -framework)) { + v ~= s,^-l,, + v ~= s,^-lib,, + v ~= s,.lib$,, + out += $$v + } + } + return ($$join(out, ";")) +} diff --git a/mkspecs/features/ctest_testcase.prf b/mkspecs/features/ctest_testcase.prf index 3045a21672..be972e0864 100644 --- a/mkspecs/features/ctest_testcase.prf +++ b/mkspecs/features/ctest_testcase.prf @@ -57,6 +57,8 @@ isEmpty(CMAKE_VERSION) { dependentmodules -= $$CMAKE_QT_MODULES_UNDER_TEST dependentmodules = $$cmakeModuleList($$dependentmodules) + contains(QT_CONFIG, angle): CMAKE_ANGLE_DEFINE = -DQT_WITH_ANGLE=True + CMAKE_MODULE_VERSIONS = CMAKE_MODULES_UNDER_TEST = for (MODULE_UNDER_TEST, CMAKE_QT_MODULES_UNDER_TEST) { @@ -74,6 +76,7 @@ isEmpty(CMAKE_VERSION) { cmake $$_PRO_FILE_PWD_ $$CMAKE_GENERATOR \ -DCMAKE_VERBOSE_MAKEFILE=1 \ $$CMAKE_MODULE_DEFINES \ + $$CMAKE_ANGLE_DEFINE \ -DCMAKE_BUILD_TYPE=$${CMAKE_BUILD_TYPE} \ -DCMAKE_PREFIX_PATH=$$CMAKE_PREFIX_PATH \ -DQt5_MODULE_TEST_DEPENDS=\"$${dependentmodules}\" \ diff --git a/src/gui/Qt5GuiConfigExtras.cmake.in b/src/gui/Qt5GuiConfigExtras.cmake.in index d9313d4364..03b98ed273 100644 --- a/src/gui/Qt5GuiConfigExtras.cmake.in +++ b/src/gui/Qt5GuiConfigExtras.cmake.in @@ -1,5 +1,50 @@ -!!IF !contains(QT_CONFIG, angle) +!!IF !mac + +!!IF !isEmpty(CMAKE_ANGLE_EGL_DLL_RELEASE) + +!!IF isEmpty(CMAKE_INCLUDE_DIR_IS_ABSOLUTE) +set(Qt5Gui_EGL_INCLUDE_DIRS \"${_qt5$${CMAKE_MODULE_NAME}_install_prefix}/$$CMAKE_INCLUDE_DIR\") +!!ELSE +set(Qt5Gui_EGL_INCLUDE_DIRS \"$$CMAKE_INCLUDE_DIR\") +!!ENDIF + +set(Qt5Gui_OPENGL_INCLUDE_DIRS ${Qt5Gui_EGL_INCLUDE_DIRS}) + +macro(_populate_qt5gui_gl_target_properties TargetName Configuration LIB_LOCATION IMPLIB_LOCATION) + set_property(TARGET Qt5::${TargetName} APPEND PROPERTY IMPORTED_CONFIGURATIONS ${Configuration}) + + set_target_properties(Qt5::${TargetName} PROPERTIES +!!IF isEmpty(CMAKE_LIB_DIR_IS_ABSOLUTE) + \"IMPORTED_LOCATION_${Configuration}\" \"${_qt5Gui_install_prefix}/$${CMAKE_LIB_DIR}${LIB_LOCATION}\" +!!ELSE + \"IMPORTED_LOCATION_${Configuration}\" \"$${CMAKE_LIB_DIR}${LIB_LOCATION}\" +!!ENDIF +!!IF isEmpty(CMAKE_LIB_DIR_IS_ABSOLUTE) + \"IMPORTED_IMPLIB_${Configuration}\" \"${_qt5Gui_install_prefix}/$${CMAKE_LIB_DIR}${IMPLIB_LOCATION}\" +!!ELSE + \"IMPORTED_IMPLIB_${Configuration}\" \"$${CMAKE_LIB_DIR}${IMPLIB_LOCATION}\" +!!ENDIF + ) +endmacro() + +add_library(Qt5::Gui_EGL SHARED IMPORTED) +_populate_qt5gui_gl_target_properties(Gui_EGL RELEASE $${CMAKE_ANGLE_EGL_DLL_RELEASE} $${CMAKE_ANGLE_EGL_IMPLIB_RELEASE}) +add_library(Qt5::Gui_GLESv2 SHARED IMPORTED) +_populate_qt5gui_gl_target_properties(Gui_GLESv2 RELEASE $${CMAKE_ANGLE_GLES2_DLL_RELEASE} $${CMAKE_ANGLE_GLES2_IMPLIB_RELEASE}) + +set_property(TARGET Qt5::Gui_EGL APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${Qt5Gui_EGL_INCLUDE_DIRS}) +set_property(TARGET Qt5::Gui_GLESv2 APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${Qt5Gui_OPENGL_INCLUDE_DIRS}) + +!!IF !isEmpty(CMAKE_DEBUG_TYPE) +_populate_qt5gui_gl_target_properties(Gui_EGL DEBUG $${CMAKE_ANGLE_EGL_DLL_DEBUG} $${CMAKE_ANGLE_EGL_IMPLIB_DEBUG}) +_populate_qt5gui_gl_target_properties(Gui_GLESv2 DEBUG $${CMAKE_ANGLE_GLES2_DLL_DEBUG} $${CMAKE_ANGLE_GLES2_IMPLIB_DEBUG}) +!!ENDIF + +set(Qt5Gui_EGL_LIBRARIES Qt5::Gui_EGL) +set(Qt5Gui_OPENGL_LIBRARIES Qt5::Gui_GLESv2) + +!!ELSE !!IF !isEmpty(CMAKE_GL_INCDIRS) @@ -17,4 +62,66 @@ unset(_qt5gui_OPENGL_INCLUDE_DIR CACHE) !!ENDIF +macro(_qt5gui_find_extra_libs Name Libs LibDir IncDirs) + set(Qt5Gui_${Name}_LIBRARIES) + set(Qt5Gui_EGL_INCLUDE_DIRS ${IncDirs}) + foreach(_lib ${Libs}) + string(REGEX REPLACE "[^_A-Za-z0-9]" "_" _cmake_lib_name ${_lib}) + if (NOT TARGET Qt5::Gui_${_cmake_lib_name}) + find_library(Qt5Gui_${_cmake_lib_name}_LIBRARY ${_lib} +!!IF !isEmpty(CROSS_COMPILE) + PATHS \"${LibDir}\" NO_DEFAULT_PATH +!!ENDIF + ) + if (NOT Qt5Gui_${_cmake_lib_name}_LIBRARY) + message(FATAL_ERROR \"Failed to find \\\"${_lib}\\\" in \\\"${LibDir}\\\", using the CMAKE_FIND_ROOT_PATH \\\"${CMAKE_FIND_ROOT_PATH}\\\".\") + endif() + add_library(Qt5::Gui_${_cmake_lib_name} SHARED IMPORTED) + set_property(TARGET Qt5::Gui_${_cmake_lib_name} APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${IncDirs}) + + set_property(TARGET Qt5::Gui_${_cmake_lib_name} APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE) + set_property(TARGET Qt5::Gui_${_cmake_lib_name} PROPERTY IMPORTED_LOCATION_RELEASE \"${Qt5Gui_${_cmake_lib_name}_LIBRARY}\") +!!IF !isEmpty(CMAKE_WINDOWS_BUILD) + set_property(TARGET Qt5::Gui_${_cmake_lib_name} PROPERTY IMPORTED_IMPLIB_RELEASE \"${Qt5Gui_${_cmake_lib_name}_LIBRARY}\") +!!ENDIF + unset(Qt5Gui_${_cmake_lib_name}_LIBRARY CACHE) + + find_library(Qt5Gui_${_cmake_lib_name}_LIBRARY_DEBUG ${_lib}d + PATHS \"${LibDir}\" NO_DEFAULT_PATH) + if (Qt5Gui_${_cmake_lib_name}_LIBRARY_DEBUG) + set_property(TARGET Qt5::Gui_${_cmake_lib_name} APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG) + set_property(TARGET Qt5::Gui_${_cmake_lib_name} PROPERTY IMPORTED_LOCATION_DEBUG \"${Qt5Gui_${_cmake_lib_name}_LIBRARY_DEBUG}\") +!!IF !isEmpty(CMAKE_WINDOWS_BUILD) + set_property(TARGET Qt5::Gui_${_cmake_lib_name} PROPERTY IMPORTED_IMPLIB_DEBUG \"${Qt5Gui_${_cmake_lib_name}_LIBRARY_DEBUG}\") +!!ENDIF + endif() + unset(Qt5Gui_${_cmake_lib_name}_LIBRARY_DEBUG CACHE) + endif() + list(APPEND Qt5Gui_${Name}_LIBRARIES Qt5::Gui_${_cmake_lib_name}) + endforeach() +endmacro() + + +!!IF !isEmpty(CMAKE_EGL_LIBS) +_qt5gui_find_extra_libs(EGL \"$$CMAKE_EGL_LIBS\" \"$$CMAKE_EGL_LIBDIR\" \"$$CMAKE_EGL_INCDIRS\") +!!ENDIF + +!!IF !isEmpty(CMAKE_OPENGL_LIBS) +_qt5gui_find_extra_libs(OPENGL \"$$CMAKE_OPENGL_LIBS\" \"$$CMAKE_OPENGL_LIBDIR\" \"$$CMAKE_OPENGL_INCDIRS\") + +!!ENDIF + +!!ENDIF + +set(Qt5Gui_OPENGL_IMPLEMENTATION $$CMAKE_QT_OPENGL_IMPLEMENTATION) + +get_target_property(_configs Qt5::Gui IMPORTED_CONFIGURATIONS) +foreach(_config ${_configs}) + set_property(TARGET Qt5::Gui APPEND PROPERTY + IMPORTED_LINK_DEPENDENT_LIBRARIES_${_config} + ${Qt5Gui_EGL_LIBRARIES} ${Qt5Gui_OPENGL_LIBRARIES} + ) +endforeach() +unset(_configs) + !!ENDIF diff --git a/src/gui/gui.pro b/src/gui/gui.pro index 9238fd91a4..062f00c4c4 100644 --- a/src/gui/gui.pro +++ b/src/gui/gui.pro @@ -37,18 +37,49 @@ QMAKE_LIBS += $$QMAKE_LIBS_GUI load(cmake_functions) -!contains(QT_CONFIG, angle) { +win32: CMAKE_WINDOWS_BUILD = True + +contains(QT_CONFIG, angle) { + CMAKE_GL_INCDIRS = $$CMAKE_INCLUDE_DIR + CMAKE_ANGLE_EGL_DLL_RELEASE = libEGL.dll + CMAKE_ANGLE_EGL_IMPLIB_RELEASE = libEGL.lib + CMAKE_ANGLE_GLES2_DLL_RELEASE = libGLESv2.dll + CMAKE_ANGLE_GLES2_IMPLIB_RELEASE = libGLESv2.lib + CMAKE_ANGLE_EGL_DLL_DEBUG = libEGLd.dll + CMAKE_ANGLE_EGL_IMPLIB_DEBUG = libEGLd.lib + CMAKE_ANGLE_GLES2_DLL_DEBUG = libGLESv2d.dll + CMAKE_ANGLE_GLES2_IMPLIB_DEBUG = libGLESv2d.lib + + CMAKE_QT_OPENGL_IMPLEMENTATION = GLESv2 +} else { + CMAKE_EGL_LIBS = $$cmakeProcessLibs($$QMAKE_LIBS_EGL) + !isEmpty(QMAKE_LIBDIR_EGL): CMAKE_EGL_LIBDIR += $$cmakeTargetPath($$QMAKE_LIBDIR_EGL) + contains(QT_CONFIG, opengles1) { - CMAKE_GL_INCDIRS = $$cmakeTargetPaths($$QMAKE_INCDIR_OPENGL_ES1) + !isEmpty(QMAKE_INCDIR_OPENGL_ES1): CMAKE_GL_INCDIRS = $$cmakeTargetPaths($$QMAKE_INCDIR_OPENGL_ES1) + CMAKE_OPENGL_INCDIRS = $$cmakePortablePaths($$QMAKE_INCDIR_OPENGL_ES1) + CMAKE_OPENGL_LIBS = $$cmakeProcessLibs($$QMAKE_LIBS_OPENGL_ES1) + !isEmpty(QMAKE_LIBDIR_OPENGL_ES1): CMAKE_OPENGL_LIBDIR = $$cmakePortablePaths($$QMAKE_LIBDIR_OPENGL_ES1) CMAKE_GL_HEADER_NAME = GLES/gl.h + CMAKE_QT_OPENGL_IMPLEMENTATION = GLES } else:contains(QT_CONFIG, opengles2) { - CMAKE_GL_INCDIRS = $$cmakeTargetPaths($$QMAKE_INCDIR_OPENGL_ES2) + !isEmpty(QMAKE_INCDIR_OPENGL_ES2): CMAKE_GL_INCDIRS = $$cmakeTargetPaths($$QMAKE_INCDIR_OPENGL_ES2) + CMAKE_OPENGL_INCDIRS = $$cmakePortablePaths($$QMAKE_INCDIR_OPENGL_ES2) + CMAKE_OPENGL_LIBS = $$cmakeProcessLibs($$QMAKE_LIBS_OPENGL_ES2) + !isEmpty(QMAKE_LIBDIR_OPENGL_ES2): CMAKE_OPENGL_LIBDIR = $$cmakePortablePaths($$QMAKE_LIBDIR_OPENGL_ES2) CMAKE_GL_HEADER_NAME = GLES2/gl2.h + CMAKE_QT_OPENGL_IMPLEMENTATION = GLESv2 } else { - CMAKE_GL_INCDIRS = $$cmakeTargetPaths($$QMAKE_INCDIR_OPENGL) + !isEmpty(QMAKE_INCDIR_OPENGL): CMAKE_GL_INCDIRS = $$cmakeTargetPaths($$QMAKE_INCDIR_OPENGL) + CMAKE_OPENGL_INCDIRS = $$cmakePortablePaths($$QMAKE_INCDIR_OPENGL) + CMAKE_OPENGL_LIBS = $$cmakeProcessLibs($$QMAKE_LIBS_OPENGL) + !isEmpty(QMAKE_LIBDIR_OPENGL): CMAKE_OPENGL_LIBDIR = $$cmakePortablePaths($$QMAKE_LIBDIR_OPENGL) CMAKE_GL_HEADER_NAME = GL/gl.h mac: CMAKE_GL_HEADER_NAME = gl.h + CMAKE_QT_OPENGL_IMPLEMENTATION = GL } } +CMAKE_EGL_INCDIRS = $$cmakePortablePaths($$QMAKE_INCDIR_EGL) + QMAKE_DYNAMIC_LIST_FILE = $$PWD/QtGui.dynlist diff --git a/tests/auto/cmake/CMakeLists.txt b/tests/auto/cmake/CMakeLists.txt index 77cf81989a..ea218f630f 100644 --- a/tests/auto/cmake/CMakeLists.txt +++ b/tests/auto/cmake/CMakeLists.txt @@ -121,6 +121,12 @@ test_module_includes( ) expect_pass(test_concurrent_module) expect_pass(test_openglextensions_module) +if (NOT APPLE) + if (QT_WITH_ANGLE OR NOT WIN32) + expect_pass(test_egl_lib) + endif() + expect_pass(test_opengl_lib) +endif() if (NOT CMAKE_VERSION VERSION_LESS 2.8.11) expect_pass(test_interface) diff --git a/tests/auto/cmake/test_egl_lib/CMakeLists.txt b/tests/auto/cmake/test_egl_lib/CMakeLists.txt new file mode 100644 index 0000000000..87a598fa99 --- /dev/null +++ b/tests/auto/cmake/test_egl_lib/CMakeLists.txt @@ -0,0 +1,14 @@ + +cmake_minimum_required(VERSION 2.8) + +project(test_egl_lib) + +find_package(Qt5Gui REQUIRED) + +include_directories(${Qt5Gui_INCLUDE_DIRS} ${Qt5Gui_EGL_INCLUDE_DIRS} ) +add_definitions(${Qt5Gui_DEFINITIONS}) + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Gui_EXECUTABLE_COMPILE_FLAGS}") + +add_executable(myobject main.cpp ) +target_link_libraries(myobject ${Qt5Gui_LIBRARIES} ${Qt5Gui_EGL_LIBRARIES}) diff --git a/tests/auto/cmake/test_egl_lib/main.cpp b/tests/auto/cmake/test_egl_lib/main.cpp new file mode 100644 index 0000000000..f3a9dc6cd1 --- /dev/null +++ b/tests/auto/cmake/test_egl_lib/main.cpp @@ -0,0 +1,48 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Stephen Kelly +** 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$ +** +****************************************************************************/ + +#include + +int main(int argc, char **argv) +{ + eglGetError(); + return 0; +} diff --git a/tests/auto/cmake/test_opengl_lib/CMakeLists.txt b/tests/auto/cmake/test_opengl_lib/CMakeLists.txt new file mode 100644 index 0000000000..d602bcda9b --- /dev/null +++ b/tests/auto/cmake/test_opengl_lib/CMakeLists.txt @@ -0,0 +1,24 @@ + +cmake_minimum_required(VERSION 2.8) + +project(test_opengl_lib) + +find_package(Qt5Gui REQUIRED) + +include_directories(${Qt5Gui_INCLUDE_DIRS} ${Qt5Gui_OPENGL_INCLUDE_DIRS} ) +add_definitions(${Qt5Gui_DEFINITIONS}) + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Gui_EXECUTABLE_COMPILE_FLAGS}") + +if (${Qt5Gui_OPENGL_IMPLEMENTATION} STREQUAL GLES) + add_definitions(-DGL_IMPLEMENTATION_GLES1) +elseif (${Qt5Gui_OPENGL_IMPLEMENTATION} STREQUAL GLESv2) + add_definitions(-DGL_IMPLEMENTATION_GLES2) +elseif (${Qt5Gui_OPENGL_IMPLEMENTATION} STREQUAL GL) + add_definitions(-DGL_IMPLEMENTATION_GL) +else() + message(SEND_ERROR "Qt5Gui_OPENGL_IMPLEMENTATION does not contain valid data.") +endif() + +add_executable(myobject main.cpp ) +target_link_libraries(myobject ${Qt5Gui_LIBRARIES} ${Qt5Gui_OPENGL_LIBRARIES}) diff --git a/tests/auto/cmake/test_opengl_lib/main.cpp b/tests/auto/cmake/test_opengl_lib/main.cpp new file mode 100644 index 0000000000..450b759bc8 --- /dev/null +++ b/tests/auto/cmake/test_opengl_lib/main.cpp @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Stephen Kelly +** 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$ +** +****************************************************************************/ + + +#if GL_IMPLEMENTATION_GLES1 +#include +#elif GL_IMPLEMENTATION_GLES2 +#include +#elif GL_IMPLEMENTATION_GL + +#include +#ifdef Q_OS_WIN +#include +#endif + +#ifdef Q_OS_MAC +#include +#else +#include +#endif +#endif + +int main(int argc, char **argv) +{ + glGetError(); + return 0; +} -- cgit v1.2.3 From e5e54a9ceb760e992001e0846a9b608107b13620 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Mon, 22 Apr 2013 15:53:27 +0200 Subject: Accessibility Windows: always check for negative child ids MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some screen readers will pass in child id's that are negative as response to notifications. We should always check for negative id's on incoming calls. Task-number: QTBUG-30792 Change-Id: Idaba3d1931d35ed068cfd9f20e70aa26da427616 Reviewed-by: Friedemann Kleint Reviewed-by: Jan Arve Sæther --- .../windows/accessible/qwindowsmsaaaccessible.cpp | 27 +++++----------------- .../windows/accessible/qwindowsmsaaaccessible.h | 20 ++++++++++++---- 2 files changed, 21 insertions(+), 26 deletions(-) diff --git a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp index 7eb1bd30c0..ce61a8b092 100644 --- a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp +++ b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp @@ -721,22 +721,7 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accChild(VARIANT varChildI if (varChildID.vt != VT_I4) return E_INVALIDARG; - - int childIndex = varChildID.lVal; - - QAccessibleInterface *acc = 0; - - - if (childIndex == 0) { - // Yes, some AT clients (Active Accessibility Object Inspector) - // actually ask for the same object. As a consequence, we need to clone ourselves: - acc = accessible; - } else if (childIndex < 0) { - acc = QAccessible::accessibleInterface((QAccessible::Id)childIndex); - } else { - acc = accessible->child(childIndex - 1); - } - + QAccessibleInterface *acc = childPointer(accessible, varChildID); if (acc) { *ppdispChild = QWindowsAccessibility::wrap(acc); return S_OK; @@ -825,7 +810,7 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accDescription(VARIANT var QString descr; if (varID.lVal) { - QAccessibleInterface *child = childPointer(varID); + QAccessibleInterface *child = childPointer(accessible, varID); if (!child) return E_FAIL; descr = child->text(QAccessible::Description); @@ -850,7 +835,7 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accHelp(VARIANT varID, BST QString help; if (varID.lVal) { - QAccessibleInterface *child = childPointer(varID); + QAccessibleInterface *child = childPointer(accessible, varID); if (!child) return E_FAIL; help = child->text(QAccessible::Help); @@ -909,7 +894,7 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accName(VARIANT varID, BST QString name; if (varID.lVal) { - QAccessibleInterface *child = childPointer(varID); + QAccessibleInterface *child = childPointer(accessible, varID); if (!child) return E_FAIL; name = child->text(QAccessible::Name); @@ -952,7 +937,7 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accRole(VARIANT varID, VAR QAccessible::Role role; if (varID.lVal) { - QAccessibleInterface *child = childPointer(varID); + QAccessibleInterface *child = childPointer(accessible, varID); if (!child) return E_FAIL; role = child->role(); @@ -987,7 +972,7 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accState(VARIANT varID, VA QAccessible::State state; if (varID.lVal) { - QAccessibleInterface *child = childPointer(varID); + QAccessibleInterface *child = childPointer(accessible, varID); if (!child) return E_FAIL; state = child->state(); diff --git a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.h b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.h index ef17acf3e9..d4f141c5d8 100644 --- a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.h +++ b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.h @@ -153,13 +153,23 @@ protected: return 0; } - QAccessibleInterface *childPointer(VARIANT varID) + static QAccessibleInterface *childPointer(QAccessibleInterface *parent, VARIANT varID) { // -1 since windows API always uses 1 for the first child - QAccessibleInterface *iface = accessibleInterface(); - if (iface) - return accessibleInterface()->child(varID.lVal - 1); - return 0; + Q_ASSERT(parent); + + QAccessibleInterface *acc = 0; + int childIndex = varID.lVal; + if (childIndex == 0) { + // Yes, some AT clients (Active Accessibility Object Inspector) + // actually ask for the same object. As a consequence, we need to clone ourselves: + acc = parent; + } else if (childIndex < 0) { + acc = QAccessible::accessibleInterface((QAccessible::Id)childIndex); + } else { + acc = parent->child(childIndex - 1); + } + return acc; } private: -- cgit v1.2.3 From ccb7db2ee35b8efb0030283856a9b9f5a1ff419d Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 22 Apr 2013 07:53:36 -0700 Subject: Document that the mutex passed to QWaitCondition::wait must be locked Simply say that the behaviour is undefined if you don't do what you must do. I don't want to introduce a check: it can't be done reliably anyway. Task-number: QTBUG-30806 Change-Id: Iba1bbbdfe62ffcb133f9c52215efdcc0ee7bd9bd Reviewed-by: Olivier Goffart --- src/corelib/thread/qwaitcondition.qdoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/thread/qwaitcondition.qdoc b/src/corelib/thread/qwaitcondition.qdoc index 68788e0b3f..9aa633a210 100644 --- a/src/corelib/thread/qwaitcondition.qdoc +++ b/src/corelib/thread/qwaitcondition.qdoc @@ -124,8 +124,8 @@ Releases the \a lockedMutex and waits on the wait condition. The \a lockedMutex must be initially locked by the calling thread. If \a - lockedMutex is not in a locked state, this function returns - immediately. If \a lockedMutex is a recursive mutex, this function + lockedMutex is not in a locked state, the behavior is undefined. If + \a lockedMutex is a recursive mutex, this function returns immediately. The \a lockedMutex will be unlocked, and the calling thread will block until either of these conditions is met: -- cgit v1.2.3 From 44d415b334b00fb28809a49e3b20bae2b27c669a Mon Sep 17 00:00:00 2001 From: Stanislav Ionascu Date: Thu, 18 Apr 2013 22:34:46 +0200 Subject: Configure: Provide -no-gui option for Windows host builds. Change-Id: I5f1fd9c39db31410c6e17f3e0dd90a27d35428ed Reviewed-by: Oswald Buddenhagen --- tools/configure/configureapp.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index dc11c0d0a2..a18aac3209 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -214,6 +214,7 @@ Configure::Configure(int& argc, char** argv) dictionary[ "QMAKE_INTERNAL" ] = "no"; dictionary[ "PROCESS" ] = "partial"; dictionary[ "WIDGETS" ] = "yes"; + dictionary[ "GUI" ] = "yes"; dictionary[ "RTTI" ] = "yes"; dictionary[ "STRIP" ] = "yes"; dictionary[ "SSE2" ] = "auto"; @@ -811,6 +812,11 @@ void Configure::parseCmdLine() else if (configCmdLine.at(i) == "-no-widgets") dictionary[ "WIDGETS" ] = "no"; + else if (configCmdLine.at(i) == "-gui") + dictionary[ "GUI" ] = "yes"; + else if (configCmdLine.at(i) == "-no-gui") + dictionary[ "GUI" ] = "no"; + else if (configCmdLine.at(i) == "-rtti") dictionary[ "RTTI" ] = "yes"; else if (configCmdLine.at(i) == "-no-rtti") @@ -1724,6 +1730,7 @@ bool Configure::displayHelp() desc( "-skip ", "Exclude an entire module from the build.\n"); desc("WIDGETS", "no", "-no-widgets", "Disable Qt Widgets module.\n"); + desc("GUI", "no", "-no-gui", "Disable Qt GUI module.\n"); desc("ACCESSIBILITY", "no", "-no-accessibility", "Disable accessibility support.\n"); desc( "", "Disabling accessibility is not recommended, as it will break QStyle\n" @@ -2494,6 +2501,9 @@ void Configure::generateOutputVars() if (dictionary[ "WIDGETS" ] == "no") qtConfig += "no-widgets"; + if (dictionary[ "GUI" ] == "no") + qtConfig += "no-gui"; + // Compression -------------------------------------------------- if (dictionary[ "ZLIB" ] == "qt") qtConfig += "zlib"; @@ -3327,6 +3337,7 @@ void Configure::generateConfigfiles() if (dictionary["ACCESSIBILITY"] == "no") qconfigList += "QT_NO_ACCESSIBILITY"; if (dictionary["WIDGETS"] == "no") qconfigList += "QT_NO_WIDGETS"; + if (dictionary["GUI"] == "no") qconfigList += "QT_NO_GUI"; if (dictionary["OPENGL"] == "no") qconfigList += "QT_NO_OPENGL"; if (dictionary["OPENVG"] == "no") qconfigList += "QT_NO_OPENVG"; if (dictionary["OPENSSL"] == "no") { @@ -3516,6 +3527,7 @@ void Configure::displayConfig() sout << "OpenSSL support............." << dictionary[ "OPENSSL" ] << endl; sout << "Qt D-Bus support............" << dictionary[ "DBUS" ] << endl; sout << "Qt Widgets module support..." << dictionary[ "WIDGETS" ] << endl; + sout << "Qt GUI module support......." << dictionary[ "GUI" ] << endl; sout << "QML debugging..............." << dictionary[ "QML_DEBUG" ] << endl; sout << "DirectWrite support........." << dictionary[ "DIRECTWRITE" ] << endl; sout << "Use system proxies.........." << dictionary[ "SYSTEM_PROXIES" ] << endl << endl; -- cgit v1.2.3 From d576d77f03cc361e6b59721048af3293a22852c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Mon, 22 Apr 2013 13:05:24 +0200 Subject: Don't set WA_AcceptTouchEvents on Mac OS X. Setting this flag causes scroll event lag, so we want to keep it off for all widgets that do not need touch events. QPanGestureRecognizer is installed on all QAbstractScrollAreas. Prevent it from setting the flag. Change-Id: Idd4fcc545ff26377607b56f75db75c2865a5fc82 Reviewed-by: Gabriel de Dietrich --- src/widgets/kernel/qstandardgestures.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/widgets/kernel/qstandardgestures.cpp b/src/widgets/kernel/qstandardgestures.cpp index e3131e7e56..f4307e9737 100644 --- a/src/widgets/kernel/qstandardgestures.cpp +++ b/src/widgets/kernel/qstandardgestures.cpp @@ -59,8 +59,8 @@ QPanGestureRecognizer::QPanGestureRecognizer() QGesture *QPanGestureRecognizer::create(QObject *target) { if (target && target->isWidgetType()) { -#if defined(Q_OS_WIN) && !defined(QT_NO_NATIVE_GESTURES) - // for scroll areas on Windows we want to use native gestures instead +#if ((defined(Q_OS_MAC) && !defined(Q_OS_IOS)) || defined(Q_OS_WIN)) && !defined(QT_NO_NATIVE_GESTURES) + // for scroll areas on Windows and Mac OS X we want to use native gestures instead if (!qobject_cast(target->parent())) static_cast(target)->setAttribute(Qt::WA_AcceptTouchEvents); #else -- cgit v1.2.3 From f9ecaa8825ee71159420855270bd5e6462bb50af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Wed, 17 Apr 2013 10:56:56 +0200 Subject: Return GroupRole for unknown accessibility roles. UnknownRole draws attention from the screen reader and makes it focus on the unknown item. GroupRole is ignored and passes focus to child items. Change-Id: If7b4cd9ec02b1890929a709b84d897f452c39587 Reviewed-by: Frederik Gladhorn --- src/plugins/platforms/cocoa/qcocoaaccessibility.mm | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm index 25780e79f4..9c38a874e5 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm +++ b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm @@ -165,8 +165,11 @@ NSString *macRole(QAccessibleInterface *interface) return roleMap[qtRole]; } - // MAC_ACCESSIBILTY_DEBUG() << "return NSAccessibilityUnknownRole"; - return NSAccessibilityUnknownRole; + // Treat unknown Qt roles as generic group container items. Returning + // NSAccessibilityUnknownRole is also possible but makes the screen + // reader focus on the item instead of passing focus to child items. + // MAC_ACCESSIBILTY_DEBUG() << "return NSAccessibilityGroupRole for unknown Qt role"; + return NSAccessibilityGroupRole; } /* -- cgit v1.2.3 From 8a8d47d0611c43e75cc69bae292a1002bf415b22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Tue, 16 Apr 2013 16:30:51 +0200 Subject: Use qAccessibleRoleString to stringify roles. Change-Id: I886d48aa094aee6ac2abe2ec1f938071281d1676 Reviewed-by: Frederik Gladhorn --- .../accessibilityinspector/accessibilityinspector.cpp | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/util/accessibilityinspector/accessibilityinspector.cpp b/util/accessibilityinspector/accessibilityinspector.cpp index bf55c36df9..33142039e8 100644 --- a/util/accessibilityinspector/accessibilityinspector.cpp +++ b/util/accessibilityinspector/accessibilityinspector.cpp @@ -164,23 +164,6 @@ void AccessibilityInspector::saveWindowGeometry() QString translateRole(QAccessible::Role role) { - if (role == 0x2B) - return "PushButton"; - if (role == 0x2C) - return "CheckBox"; - if (role == 0x2D) - return "RadioButton"; - if (role == 0xA) - return "Client"; - if (role == 0x29) - return "Static Text"; - if (role == 0x33) - return "Slider"; - if (role == 0x33) - return "Slider"; - if (role == 0x10) - return "Pane"; - - return QString::number(role, 16); + return qAccessibleRoleString(role); } -- cgit v1.2.3 From f898614b76311c42454f8a1442db9cacda21c35d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Tue, 16 Apr 2013 17:03:22 +0200 Subject: Don't show a separate inspector for child windows. Change-Id: I5cd0060cdfe1990e2620010d2f0eb281fd225142 Reviewed-by: Frederik Gladhorn --- util/accessibilityinspector/accessibilityinspector.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/util/accessibilityinspector/accessibilityinspector.cpp b/util/accessibilityinspector/accessibilityinspector.cpp index 33142039e8..df83377296 100644 --- a/util/accessibilityinspector/accessibilityinspector.cpp +++ b/util/accessibilityinspector/accessibilityinspector.cpp @@ -99,6 +99,8 @@ AccessibilityInspector::~AccessibilityInspector() void AccessibilityInspector::inspectWindow(QWindow *window) { qDebug() << "AccessibilityInspector::inspectWindow()" << window; + if (window->parent() || window->transientParent()) + return; optionsWidget = new OptionsWidget(); -- cgit v1.2.3 From 7dd81686e8e9ee86624c5bcca10688cfb360dcb8 Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Mon, 22 Apr 2013 12:11:37 +0200 Subject: Fix QKeySequence::toString() returning gibberish for Qt::KeypadModifier This is the patch from the bug report with a few alterations to get it to compile, and also with the GroupSwitchModifier code removed, as this patch just focuses on Qt::KeypadModifier. The problem was determined to be in QKeySequencePrivate::encodeString, which doesn't handle the Qt::KeypadModifier flag. Task-number: QTBUG-4022 Change-Id: Ic981eb8b5cd88c7b36892d3019b8175db4b7b6f2 Reviewed-by: David Faure (KDE) --- src/corelib/global/qnamespace.h | 4 ++++ src/gui/kernel/qkeysequence.cpp | 13 +++++++++---- tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp | 5 +++++ 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index f130288a24..95d9baafd5 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -138,6 +138,10 @@ public: Q_DECLARE_FLAGS(KeyboardModifiers, KeyboardModifier) //shorter names for shortcuts + // The use of all-caps identifiers has the potential for clashing with + // user-defined or third-party macros. More so when the identifiers are not + // "namespace"-prefixed. This is considered bad practice and is why + // KeypadModifier was not added to the Modifier enum. enum Modifier { META = Qt::MetaModifier, SHIFT = Qt::ShiftModifier, diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp index 44de8c5847..a0255f610a 100644 --- a/src/gui/kernel/qkeysequence.cpp +++ b/src/gui/kernel/qkeysequence.cpp @@ -1225,7 +1225,8 @@ int QKeySequencePrivate::decodeString(const QString &str, QKeySequence::Sequence *gmodifs << QModifKeyName(Qt::CTRL, QLatin1String("ctrl+")) << QModifKeyName(Qt::SHIFT, QLatin1String("shift+")) << QModifKeyName(Qt::ALT, QLatin1String("alt+")) - << QModifKeyName(Qt::META, QLatin1String("meta+")); + << QModifKeyName(Qt::META, QLatin1String("meta+")) + << QModifKeyName(Qt::KeypadModifier, QLatin1String("numpad+")); } } else { gmodifs = globalPortableModifs(); @@ -1233,7 +1234,8 @@ int QKeySequencePrivate::decodeString(const QString &str, QKeySequence::Sequence *gmodifs << QModifKeyName(Qt::CTRL, QLatin1String("ctrl+")) << QModifKeyName(Qt::SHIFT, QLatin1String("shift+")) << QModifKeyName(Qt::ALT, QLatin1String("alt+")) - << QModifKeyName(Qt::META, QLatin1String("meta+")); + << QModifKeyName(Qt::META, QLatin1String("meta+")) + << QModifKeyName(Qt::KeypadModifier, QLatin1String("numpad+")); } } if (!gmodifs) return ret; @@ -1244,7 +1246,8 @@ int QKeySequencePrivate::decodeString(const QString &str, QKeySequence::Sequence modifs << QModifKeyName(Qt::CTRL, QCoreApplication::translate("QShortcut", "Ctrl").toLower().append(QLatin1Char('+'))) << QModifKeyName(Qt::SHIFT, QCoreApplication::translate("QShortcut", "Shift").toLower().append(QLatin1Char('+'))) << QModifKeyName(Qt::ALT, QCoreApplication::translate("QShortcut", "Alt").toLower().append(QLatin1Char('+'))) - << QModifKeyName(Qt::META, QCoreApplication::translate("QShortcut", "Meta").toLower().append(QLatin1Char('+'))); + << QModifKeyName(Qt::META, QCoreApplication::translate("QShortcut", "Meta").toLower().append(QLatin1Char('+'))) + << QModifKeyName(Qt::KeypadModifier, QCoreApplication::translate("QShortcut", "Numpad").toLower().append(QLatin1Char('+'))); } modifs += *gmodifs; // Test non-translated ones last @@ -1418,10 +1421,12 @@ QString QKeySequencePrivate::encodeString(int key, QKeySequence::SequenceFormat addKey(s, nativeText ? QCoreApplication::translate("QShortcut", "Alt") : QString::fromLatin1("Alt"), format); if ((key & Qt::SHIFT) == Qt::SHIFT) addKey(s, nativeText ? QCoreApplication::translate("QShortcut", "Shift") : QString::fromLatin1("Shift"), format); + if ((key & Qt::KeypadModifier) == Qt::KeypadModifier) + addKey(s, nativeText ? QCoreApplication::translate("QShortcut", "Numpad") : QString::fromLatin1("Numpad"), format); } - key &= ~(Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier); + key &= ~(Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier | Qt::KeypadModifier); QString p; if (key && key < Qt::Key_Escape && key != Qt::Key_Space) { diff --git a/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp b/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp index a6134de497..c77b4eea42 100644 --- a/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp +++ b/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp @@ -510,6 +510,11 @@ void tst_QKeySequence::toStringFromKeycode_data() QTest::newRow("A") << QKeySequence(Qt::Key_A) << "A"; QTest::newRow("-1") << QKeySequence(-1) << ""; QTest::newRow("Unknown") << QKeySequence(Qt::Key_unknown) << ""; + QTest::newRow("Ctrl+Numpad+Ins") << QKeySequence(Qt::ControlModifier | Qt::KeypadModifier | Qt::Key_Insert) << "Ctrl+Numpad+Ins"; + QTest::newRow("Ctrl+Numpad+Del") << QKeySequence(Qt::ControlModifier | Qt::KeypadModifier | Qt::Key_Delete) << "Ctrl+Numpad+Del"; + QTest::newRow("Ctrl+Alt+Numpad+Del") << QKeySequence(Qt::ControlModifier | Qt::AltModifier | Qt::KeypadModifier | Qt::Key_Delete) << "Ctrl+Alt+Numpad+Del"; + QTest::newRow("Ctrl+Ins") << QKeySequence(Qt::ControlModifier | Qt::Key_Insert) << "Ctrl+Ins"; + QTest::newRow("Ctrl+Numpad+Ins(1)") << QKeySequence(Qt::Key_Insert | Qt::KeypadModifier | Qt::ControlModifier) << "Ctrl+Numpad+Ins"; } void tst_QKeySequence::toStringFromKeycode() -- cgit v1.2.3 From 3b992f8319b673495ffc74c65ed6a6761e88913c Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Mon, 22 Apr 2013 18:14:09 +0200 Subject: Enforce focus policy in item delegate's editor Focus policy can be wider in this case given the limited scope of the editor widget. This helps workaround platform specific focus policies, like on Mac, were focus can be restricted depending on the widget type. Task-number: QTBUG-30715 Change-Id: I69acf8ebff4ba16d473964c91680a1cb0235e3cf Reviewed-by: Friedemann Kleint Reviewed-by: Jake Petroules Reviewed-by: Stephen Kelly --- src/widgets/itemviews/qitemdelegate.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/widgets/itemviews/qitemdelegate.cpp b/src/widgets/itemviews/qitemdelegate.cpp index f2c3c4702f..7d8512adc4 100644 --- a/src/widgets/itemviews/qitemdelegate.cpp +++ b/src/widgets/itemviews/qitemdelegate.cpp @@ -523,7 +523,10 @@ QWidget *QItemDelegate::createEditor(QWidget *parent, const QItemEditorFactory *factory = d->f; if (factory == 0) factory = QItemEditorFactory::defaultFactory(); - return factory->createEditor(index.data(Qt::EditRole).userType(), parent); + QWidget *w = factory->createEditor(index.data(Qt::EditRole).userType(), parent); + if (w) + w->setFocusPolicy(Qt::WheelFocus); + return w; } /*! -- cgit v1.2.3 From 2fbfad8b0d106bb4f9babaf27c12e8665059f451 Mon Sep 17 00:00:00 2001 From: Libor Tomsik Date: Sat, 30 Mar 2013 18:15:56 +0100 Subject: Added grabbing option for qevdevkeyboard and mouse. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added option grab=1/0 which allows user to choose using environment variable if the application will exclusively grab the input device or let the OS read it in paralel(default). Task-number: QTBUG-30004 Change-Id: If3caa8419584be46f320931ddb152a41893d8693 Reviewed-by: Samuel Rødal Reviewed-by: Andy Nichols --- src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp | 4 ++++ src/platformsupport/input/evdevmouse/qevdevmousehandler.cpp | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp index 9719319b03..26dc116f91 100644 --- a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp +++ b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp @@ -104,6 +104,7 @@ QEvdevKeyboardHandler *QEvdevKeyboardHandler::create(const QString &device, cons int repeatRate = 80; bool disableZap = false; bool enableCompose = false; + int grab = 0; QStringList args = specification.split(QLatin1Char(':')); foreach (const QString &arg, args) { @@ -117,6 +118,8 @@ QEvdevKeyboardHandler *QEvdevKeyboardHandler::create(const QString &device, cons repeatDelay = arg.mid(13).toInt(); else if (arg.startsWith(QLatin1String("repeat-rate="))) repeatRate = arg.mid(12).toInt(); + else if (arg.startsWith(QLatin1String("grab="))) + grab = arg.mid(5).toInt(); } #ifdef QT_QPA_KEYMAP_DEBUG @@ -126,6 +129,7 @@ QEvdevKeyboardHandler *QEvdevKeyboardHandler::create(const QString &device, cons int fd; fd = qt_safe_open(device.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0); if (fd >= 0) { + ::ioctl(fd, EVIOCGRAB, grab); if (repeatDelay > 0 && repeatRate > 0) { int kbdrep[2] = { repeatDelay, repeatRate }; ::ioctl(fd, EVIOCSREP, kbdrep); diff --git a/src/platformsupport/input/evdevmouse/qevdevmousehandler.cpp b/src/platformsupport/input/evdevmouse/qevdevmousehandler.cpp index 27c5f18d1a..92f807095f 100644 --- a/src/platformsupport/input/evdevmouse/qevdevmousehandler.cpp +++ b/src/platformsupport/input/evdevmouse/qevdevmousehandler.cpp @@ -70,6 +70,7 @@ QEvdevMouseHandler *QEvdevMouseHandler::create(const QString &device, const QStr bool compression = true; int jitterLimit = 0; + int grab = 0; QStringList args = specification.split(QLatin1Char(':')); foreach (const QString &arg, args) { @@ -77,11 +78,14 @@ QEvdevMouseHandler *QEvdevMouseHandler::create(const QString &device, const QStr compression = false; else if (arg.startsWith(QLatin1String("dejitter="))) jitterLimit = arg.mid(9).toInt(); + else if (arg.startsWith(QLatin1String("grab="))) + grab = arg.mid(5).toInt(); } int fd; fd = qt_safe_open(device.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0); if (fd >= 0) { + ::ioctl(fd, EVIOCGRAB, grab); return new QEvdevMouseHandler(device, fd, compression, jitterLimit); } else { qWarning("Cannot open mouse input device '%s': %s", qPrintable(device), strerror(errno)); -- cgit v1.2.3 From 43e1c61a191d22cf106789fb68a7bfb9e0f58a26 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Mon, 22 Apr 2013 16:36:17 +0200 Subject: Add missing intrin.h include for __cpuid This is already fixed upstream in https://codereview.appspot.com/8615046/patch/1/2 Change-Id: I4b9e865f6b5622c484418a8381334381bc256887 Reviewed-by: Friedemann Kleint --- src/3rdparty/angle/src/libGLESv2/mathutil.h | 2 ++ ...-Add-missing-intrin.h-include-for-__cpuid.patch | 30 ++++++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 src/angle/patches/0010-Add-missing-intrin.h-include-for-__cpuid.patch diff --git a/src/3rdparty/angle/src/libGLESv2/mathutil.h b/src/3rdparty/angle/src/libGLESv2/mathutil.h index 672c443c11..bb48b94eaf 100644 --- a/src/3rdparty/angle/src/libGLESv2/mathutil.h +++ b/src/3rdparty/angle/src/libGLESv2/mathutil.h @@ -9,6 +9,8 @@ #ifndef LIBGLESV2_MATHUTIL_H_ #define LIBGLESV2_MATHUTIL_H_ +#include + #include "common/system.h" #include "common/debug.h" diff --git a/src/angle/patches/0010-Add-missing-intrin.h-include-for-__cpuid.patch b/src/angle/patches/0010-Add-missing-intrin.h-include-for-__cpuid.patch new file mode 100644 index 0000000000..ebe3de4dc9 --- /dev/null +++ b/src/angle/patches/0010-Add-missing-intrin.h-include-for-__cpuid.patch @@ -0,0 +1,30 @@ +From 142312b5cbea10257b6d3693b48817ae657018eb Mon Sep 17 00:00:00 2001 +From: Kai Koehne +Date: Mon, 22 Apr 2013 16:36:17 +0200 +Subject: [PATCH] Add missing intrin.h include for __cpuid + +This is already fixed upstream in + +https://codereview.appspot.com/8615046/patch/1/2 + +Change-Id: I4b9e865f6b5622c484418a8381334381bc256887 +--- + src/3rdparty/angle/src/libGLESv2/mathutil.h | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/3rdparty/angle/src/libGLESv2/mathutil.h b/src/3rdparty/angle/src/libGLESv2/mathutil.h +index 672c443..bb48b94 100644 +--- a/src/3rdparty/angle/src/libGLESv2/mathutil.h ++++ b/src/3rdparty/angle/src/libGLESv2/mathutil.h +@@ -9,6 +9,8 @@ + #ifndef LIBGLESV2_MATHUTIL_H_ + #define LIBGLESV2_MATHUTIL_H_ + ++#include ++ + #include "common/system.h" + #include "common/debug.h" + +-- +1.8.1.msysgit.1 + -- cgit v1.2.3 From a6e903299b8f7f5848991735645916387e29add2 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Mon, 22 Apr 2013 17:06:39 +0200 Subject: Fix def files for Mingw (32 bit) Add missing symbols. Change-Id: I73579f13b0cbc8b4b405a50b3745785e088cf82d Reviewed-by: Jonathan Liu Reviewed-by: Friedemann Kleint --- src/3rdparty/angle/src/libGLESv2/libGLESv2_mingw32.def | 2 ++ src/3rdparty/angle/src/libGLESv2/libGLESv2d_mingw32.def | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2_mingw32.def b/src/3rdparty/angle/src/libGLESv2/libGLESv2_mingw32.def index dc5900854a..0f6caf17a3 100644 --- a/src/3rdparty/angle/src/libGLESv2/libGLESv2_mingw32.def +++ b/src/3rdparty/angle/src/libGLESv2/libGLESv2_mingw32.def @@ -180,3 +180,5 @@ EXPORTS glGetCurrentContext @147 NONAME glGetProcAddress@4 @148 NONAME glBindTexImage@4 @158 NONAME + glCreateRenderer @177 NONAME + glDestroyRenderer @178 NONAME \ No newline at end of file diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2d_mingw32.def b/src/3rdparty/angle/src/libGLESv2/libGLESv2d_mingw32.def index 610e5e1173..dd92a2a12b 100644 --- a/src/3rdparty/angle/src/libGLESv2/libGLESv2d_mingw32.def +++ b/src/3rdparty/angle/src/libGLESv2/libGLESv2d_mingw32.def @@ -180,3 +180,5 @@ EXPORTS glGetCurrentContext @147 NONAME glGetProcAddress@4 @148 NONAME glBindTexImage@4 @158 NONAME + glCreateRenderer @177 NONAME + glDestroyRenderer @178 NONAME \ No newline at end of file -- cgit v1.2.3 From 941f7a5283cf7331d8b079c6b0561ab6627cf108 Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Thu, 11 Apr 2013 17:11:36 +0200 Subject: Make requestActivate() as a slot in QWindow Then it could be used in QML world. Task-number: QTBUG-28667 Change-Id: Ib65ad3b271a07ba50d3ca50d61f486f829f69119 Reviewed-by: Gunnar Sletta --- src/gui/kernel/qwindow.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/kernel/qwindow.h b/src/gui/kernel/qwindow.h index 9b1ed2c702..8f32ff6813 100644 --- a/src/gui/kernel/qwindow.h +++ b/src/gui/kernel/qwindow.h @@ -170,8 +170,6 @@ public: void setMask(const QRegion ®ion); QRegion mask() const; - void requestActivate(); - bool isActive() const; void reportContentOrientationChange(Qt::ScreenOrientation orientation); @@ -264,6 +262,8 @@ public: static QWindow *fromWinId(WId id); public Q_SLOTS: + Q_REVISION(1) void requestActivate(); + void setVisible(bool visible); void show(); -- cgit v1.2.3 From 8d60a104620c83ff89b914f4ac94742c52a8ed30 Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Wed, 10 Apr 2013 12:45:45 +0200 Subject: QWindow: expose active as property And add activeChanged signal for it. Change-Id: I9ebe9263e99863267c3a81b9286eaa5b29222085 Reviewed-by: Gunnar Sletta --- src/gui/kernel/qguiapplication.cpp | 4 ++++ src/gui/kernel/qwindow.cpp | 8 ++++++++ src/gui/kernel/qwindow.h | 2 ++ 3 files changed, 14 insertions(+) diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index fba516c135..585eca84ca 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -1640,6 +1640,10 @@ void QGuiApplicationPrivate::processActivatedEvent(QWindowSystemInterfacePrivate } emit qApp->focusWindowChanged(newFocus); + if (previous) + emit previous->activeChanged(); + if (newFocus) + emit newFocus->activeChanged(); } void QGuiApplicationPrivate::processWindowStateChangedEvent(QWindowSystemInterfacePrivate::WindowStateChangedEvent *wse) diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 8c9bc575bd..0dd85f2d56 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -873,6 +873,14 @@ bool QWindow::isExposed() const return d->exposed; } +/*! + \property QWindow::active + \brief the active status of the window + \since 5.1 + + \sa requestActivate() +*/ + /*! Returns true if the window should appear active from a style perspective. diff --git a/src/gui/kernel/qwindow.h b/src/gui/kernel/qwindow.h index 8f32ff6813..79f90f2c62 100644 --- a/src/gui/kernel/qwindow.h +++ b/src/gui/kernel/qwindow.h @@ -115,6 +115,7 @@ class Q_GUI_EXPORT QWindow : public QObject, public QSurface Q_PROPERTY(int maximumWidth READ maximumWidth WRITE setMaximumWidth NOTIFY maximumWidthChanged REVISION 1) Q_PROPERTY(int maximumHeight READ maximumHeight WRITE setMaximumHeight NOTIFY maximumHeightChanged REVISION 1) Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged) + Q_PROPERTY(bool active READ isActive NOTIFY activeChanged REVISION 1) Q_PROPERTY(Visibility visibility READ visibility WRITE setVisibility NOTIFY visibilityChanged REVISION 1) Q_PROPERTY(Qt::ScreenOrientation contentOrientation READ contentOrientation WRITE reportContentOrientationChange NOTIFY contentOrientationChanged REVISION 1) Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity NOTIFY opacityChanged REVISION 1) @@ -310,6 +311,7 @@ Q_SIGNALS: void visibleChanged(bool arg); Q_REVISION(1) void visibilityChanged(QWindow::Visibility visibility); + Q_REVISION(1) void activeChanged(); Q_REVISION(1) void contentOrientationChanged(Qt::ScreenOrientation orientation); void focusObjectChanged(QObject *object); -- cgit v1.2.3 From a7ce34dba4213927deba443e0e9c42df1769cc25 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Mon, 22 Apr 2013 15:51:05 +0200 Subject: Accessibility: Menu item should keep track of owner being valid MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The QAction may stay around while the parent/owner gets deleted. This is for example the case for some dynamically created menus. This is required for fixing QTBUG-30792 Change-Id: I7b6122edec6def69aed77502403134e1568e21c9 Reviewed-by: Friedemann Kleint Reviewed-by: Jan Arve Sæther --- src/plugins/accessible/widgets/qaccessiblemenu.cpp | 2 +- src/plugins/accessible/widgets/qaccessiblemenu.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/plugins/accessible/widgets/qaccessiblemenu.cpp b/src/plugins/accessible/widgets/qaccessiblemenu.cpp index f248e6d05e..39ac335131 100644 --- a/src/plugins/accessible/widgets/qaccessiblemenu.cpp +++ b/src/plugins/accessible/widgets/qaccessiblemenu.cpp @@ -206,7 +206,7 @@ int QAccessibleMenuItem::indexOfChild(const QAccessibleInterface * child) const bool QAccessibleMenuItem::isValid() const { - return m_action ? true : false; + return m_action && m_owner ? true : false; } QAccessibleInterface *QAccessibleMenuItem::parent() const diff --git a/src/plugins/accessible/widgets/qaccessiblemenu.h b/src/plugins/accessible/widgets/qaccessiblemenu.h index 74d118a09e..f933a4a37e 100644 --- a/src/plugins/accessible/widgets/qaccessiblemenu.h +++ b/src/plugins/accessible/widgets/qaccessiblemenu.h @@ -43,6 +43,7 @@ #define QACCESSIBLEMENU_H #include +#include QT_BEGIN_NAMESPACE @@ -120,7 +121,7 @@ protected: QAction *action() const; private: QAction *m_action; - QWidget *m_owner; // can hold either QMenu or the QMenuBar that contains the action + QPointer m_owner; // can hold either QMenu or the QMenuBar that contains the action }; #endif // QT_NO_MENU -- cgit v1.2.3 From e324f5bc0e6abb8772b29f5016afda0814d8f9cd Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Tue, 23 Apr 2013 12:01:01 +0200 Subject: Fix crash when deleting a QMenu on exit If the application object is an ancestor of QMenu, dereferencing qApp in its destructor will cause a crash. Task-number: QTBUG-30756 Change-Id: I31a33db0fd783bb210a420618911ea8b412e9a0f Reviewed-by: Frederik Gladhorn --- src/widgets/kernel/qwidget_qpa.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/kernel/qwidget_qpa.cpp b/src/widgets/kernel/qwidget_qpa.cpp index fdc72ee23c..a4da98815b 100644 --- a/src/widgets/kernel/qwidget_qpa.cpp +++ b/src/widgets/kernel/qwidget_qpa.cpp @@ -172,7 +172,7 @@ void QWidget::destroy(bool destroyWindow, bool destroySubWindows) parentWidget()->d_func()->invalidateBuffer(d->effectiveRectFor(geometry())); d->deactivateWidgetCleanup(); - if ((windowType() == Qt::Popup)) + if ((windowType() == Qt::Popup) && qApp) qApp->d_func()->closePopup(this); if (this == QApplicationPrivate::active_window) -- cgit v1.2.3 From a7dc708eb57b8db55f2dd0380fabb4a4e64a39d1 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Tue, 23 Apr 2013 12:31:23 +0200 Subject: Fix QAbstractItemModel::moveColumn() Task-number: QTBUG-30346 Change-Id: I3d6dbe1e88bb5e2748eadabb2663f30be16f8d18 Reviewed-by: Stephen Kelly Reviewed-by: Mark Brand --- src/corelib/itemmodels/qabstractitemmodel.h | 2 +- .../corelib/itemmodels/qabstractitemmodel/tst_qabstractitemmodel.cpp | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/corelib/itemmodels/qabstractitemmodel.h b/src/corelib/itemmodels/qabstractitemmodel.h index 6a57ccaca8..d5bf29212f 100644 --- a/src/corelib/itemmodels/qabstractitemmodel.h +++ b/src/corelib/itemmodels/qabstractitemmodel.h @@ -405,7 +405,7 @@ inline bool QAbstractItemModel::moveRow(const QModelIndex &sourceParent, int sou { return moveRows(sourceParent, sourceRow, 1, destinationParent, destinationChild); } inline bool QAbstractItemModel::moveColumn(const QModelIndex &sourceParent, int sourceColumn, const QModelIndex &destinationParent, int destinationChild) -{ return moveRows(sourceParent, sourceColumn, 1, destinationParent, destinationChild); } +{ return moveColumns(sourceParent, sourceColumn, 1, destinationParent, destinationChild); } inline QModelIndex QAbstractItemModel::createIndex(int arow, int acolumn, void *adata) const { return QModelIndex(arow, acolumn, adata, this); } inline QModelIndex QAbstractItemModel::createIndex(int arow, int acolumn, quintptr aid) const diff --git a/tests/auto/corelib/itemmodels/qabstractitemmodel/tst_qabstractitemmodel.cpp b/tests/auto/corelib/itemmodels/qabstractitemmodel/tst_qabstractitemmodel.cpp index d2fb56ce02..2d2ae14fb8 100644 --- a/tests/auto/corelib/itemmodels/qabstractitemmodel/tst_qabstractitemmodel.cpp +++ b/tests/auto/corelib/itemmodels/qabstractitemmodel/tst_qabstractitemmodel.cpp @@ -891,6 +891,10 @@ void tst_QAbstractItemModel::moveColumns() QCOMPARE(model.moveColumns(QModelIndex(), 6, 4, QModelIndex(), 1), true); QCOMPARE(columnsAboutToBeMovedSpy.count(), 1); QCOMPARE(columnsMovedSpy.count(), 1); + + QCOMPARE(model.moveColumn(QModelIndex(), 4, QModelIndex(), 1), true); + QCOMPARE(columnsAboutToBeMovedSpy.count(), 2); + QCOMPARE(columnsMovedSpy.count(), 2); } void tst_QAbstractItemModel::reset() -- cgit v1.2.3 From a961204d28a76f68953743b47199959e5978c1ef Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 23 Apr 2013 13:50:01 +0200 Subject: File dialog manual test: Remove dot from default suffix. Change-Id: Icadfd2103bb89b5f9ea167737d9e6af05d7a6b86 Reviewed-by: J-P Nurmi --- tests/manual/dialogs/filedialogpanel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/manual/dialogs/filedialogpanel.cpp b/tests/manual/dialogs/filedialogpanel.cpp index 636e65b684..2ca9dccf1b 100644 --- a/tests/manual/dialogs/filedialogpanel.cpp +++ b/tests/manual/dialogs/filedialogpanel.cpp @@ -385,7 +385,7 @@ void FileDialogPanel::restoreDefaults() m_readOnly->setChecked(d.isReadOnly()); m_native->setChecked(true); m_directory->setText(QDir::homePath()); - m_defaultSuffix->setText(QLatin1String(".txt")); + m_defaultSuffix->setText(QLatin1String("txt")); m_nameFilters->setPlainText(QLatin1String("Any files (*)\nImage files (*.png *.xpm *.jpg)\nText files (*.txt)")); m_selectedFileName->setText(QString()); m_selectedNameFilter->setText(QString()); -- cgit v1.2.3 From 38fea4d642c1188d2441d8fdbe147369995077ba Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Tue, 23 Apr 2013 11:56:15 +0200 Subject: Fix build with QT_NO_CLIPBOARD Change-Id: I138a29e1099e691770b9e3e094a108fc8c52f8cb Reviewed-by: Andreas Holzammer Reviewed-by: Giuseppe D'Angelo --- src/widgets/dialogs/qmessagebox.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/widgets/dialogs/qmessagebox.cpp b/src/widgets/dialogs/qmessagebox.cpp index 833320da16..4ec828ac83 100644 --- a/src/widgets/dialogs/qmessagebox.cpp +++ b/src/widgets/dialogs/qmessagebox.cpp @@ -133,10 +133,14 @@ public: bool copy() { +#ifdef QT_NO_CLIPBOARD + return false; +#else if (!copyAvailable) return false; textEdit->copy(); return true; +#endif } private slots: -- cgit v1.2.3 From 93aa83e074194f4e15f613b18808087640e51c50 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Tue, 23 Apr 2013 10:40:43 +0200 Subject: Fix typo in docs Change-Id: I3ee3e3d061fc87c0c2ea05197b37a952c8d63dd2 Reviewed-by: hjk --- src/widgets/itemviews/qtreeview.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp index 70523815e8..6aefbb5367 100644 --- a/src/widgets/itemviews/qtreeview.cpp +++ b/src/widgets/itemviews/qtreeview.cpp @@ -878,7 +878,7 @@ bool QTreeView::isSortingEnabled() const \property QTreeView::animated \brief whether animations are enabled - If this property is true the treeview will animate expandsion + If this property is true the treeview will animate expansion and collapsing of branches. If this property is false, the treeview will expand or collapse branches immediately without showing the animation. -- cgit v1.2.3 From 9c47a273ffb2f139a60faa2496351f71e379c9b4 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Mon, 22 Apr 2013 15:50:13 +0200 Subject: Accessibility: Ignore negative child indices in main window MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I6b3d0b066bf20a09b43d6d80255fb8d428d38df1 Reviewed-by: Jan Arve Sæther --- src/plugins/accessible/widgets/qaccessiblewidgets.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/accessible/widgets/qaccessiblewidgets.cpp b/src/plugins/accessible/widgets/qaccessiblewidgets.cpp index f20823f25b..59dc03666b 100644 --- a/src/plugins/accessible/widgets/qaccessiblewidgets.cpp +++ b/src/plugins/accessible/widgets/qaccessiblewidgets.cpp @@ -1127,7 +1127,7 @@ QAccessibleMainWindow::QAccessibleMainWindow(QWidget *widget) QAccessibleInterface *QAccessibleMainWindow::child(int index) const { QList kids = childWidgets(mainWindow(), true); - if (index < kids.count()) { + if (index >= 0 && index < kids.count()) { return QAccessible::queryAccessibleInterface(kids.at(index)); } return 0; -- cgit v1.2.3 From 06b6784c28eceddcbbde12419d1fc1362a071ab0 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 22 Apr 2013 17:42:26 -0700 Subject: Fix header check: you must #include qconfig.h before QT_NO_OPENGL Change-Id: I50518bd1b721d19e4712a6c11afb0a93afeaa7ea Reviewed-by: Sean Harmer --- src/gui/opengl/qopengltimerquery.h | 2 ++ src/gui/opengl/qopenglvertexarrayobject.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/gui/opengl/qopengltimerquery.h b/src/gui/opengl/qopengltimerquery.h index 649e80d6c0..c1cada9bdb 100644 --- a/src/gui/opengl/qopengltimerquery.h +++ b/src/gui/opengl/qopengltimerquery.h @@ -42,6 +42,8 @@ #ifndef QOPENGLTIMERQUERY_H #define QOPENGLTIMERQUERY_H +#include + #if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_2) #include diff --git a/src/gui/opengl/qopenglvertexarrayobject.h b/src/gui/opengl/qopenglvertexarrayobject.h index d5226d3ebd..569aeea730 100644 --- a/src/gui/opengl/qopenglvertexarrayobject.h +++ b/src/gui/opengl/qopenglvertexarrayobject.h @@ -42,6 +42,8 @@ #ifndef QOPENGLVERTEXARRAYOBJECT_H #define QOPENGLVERTEXARRAYOBJECT_H +#include + #ifndef QT_NO_OPENGL #include -- cgit v1.2.3 From 839e275249f3bd210a303ddcca32d3015cab5ca7 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Mon, 22 Apr 2013 22:00:10 +0200 Subject: Use the CMake list separator for content in a CMake list. Change-Id: I664c31d256d395d4afec81de66a84dc79ed10b9d Reviewed-by: Volker Krause Reviewed-by: Stephen Kelly --- mkspecs/features/cmake_functions.prf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkspecs/features/cmake_functions.prf b/mkspecs/features/cmake_functions.prf index 1e7c0e23f7..08295da75f 100644 --- a/mkspecs/features/cmake_functions.prf +++ b/mkspecs/features/cmake_functions.prf @@ -47,7 +47,7 @@ defineReplace(cmakePortablePaths) { for(v, variable) { out += ${CMAKE_FIND_ROOT_PATH}$$cmakeTargetPath($$v) } - return ($$join(out, " ")) + return ($$join(out, ";")) } defineReplace(cmakeProcessLibs) { -- cgit v1.2.3 From ecc11ccd6598e868193863d82c7034bfbb2c1fe6 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Tue, 23 Apr 2013 11:21:57 +0200 Subject: Set the sysroot if cross compiling the cmake tests. Change-Id: Iae268f30b86a67fcf978983ca9b12f850948dd24 Reviewed-by: Volker Krause Reviewed-by: Stephen Kelly --- src/corelib/Qt5CTestMacros.cmake | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/corelib/Qt5CTestMacros.cmake b/src/corelib/Qt5CTestMacros.cmake index 126a348b47..51537a3904 100644 --- a/src/corelib/Qt5CTestMacros.cmake +++ b/src/corelib/Qt5CTestMacros.cmake @@ -38,6 +38,10 @@ foreach(module ${CMAKE_MODULES_UNDER_TEST}) ) endforeach() +if(CMAKE_CROSSCOMPILING AND CMAKE_FIND_ROOT_PATH) + list(APPEND BUILD_OPTIONS_LIST "-DCMAKE_CXX_LINK_FLAGS=--sysroot=\"${CMAKE_FIND_ROOT_PATH}\"") +endif() + macro(expect_pass _dir) string(REPLACE "(" "_" testname "${_dir}") string(REPLACE ")" "_" testname "${testname}") -- cgit v1.2.3 From ad3b61554b56435dd44563fec21d944416dd1c84 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 22 Apr 2013 15:14:03 +0200 Subject: Move Mac translations to .cpp file for lupdate to pick them up. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-30125 Change-Id: I4e56fd3021b4ef5f344d4d36ae594dd88e2aa1bd Reviewed-by: Morten Johan Sørvig Reviewed-by: Gabriel de Dietrich --- src/plugins/platforms/cocoa/cocoa.pro | 3 + src/plugins/platforms/cocoa/messages.cpp | 96 +++++++++++++++++++++++++ src/plugins/platforms/cocoa/messages.h | 58 +++++++++++++++ src/plugins/platforms/cocoa/qcocoamenuitem.mm | 27 ++++--- src/plugins/platforms/cocoa/qcocoamenuloader.mm | 25 +------ 5 files changed, 170 insertions(+), 39 deletions(-) create mode 100644 src/plugins/platforms/cocoa/messages.cpp create mode 100644 src/plugins/platforms/cocoa/messages.h diff --git a/src/plugins/platforms/cocoa/cocoa.pro b/src/plugins/platforms/cocoa/cocoa.pro index 66c4e3c49c..a2fd8c0613 100644 --- a/src/plugins/platforms/cocoa/cocoa.pro +++ b/src/plugins/platforms/cocoa/cocoa.pro @@ -41,6 +41,8 @@ OBJECTIVE_SOURCES += main.mm \ qcocoaintrospection.mm \ qcocoakeymapper.mm \ +SOURCES += messages.cpp + HEADERS += qcocoaintegration.h \ qcocoatheme.h \ qcocoabackingstore.h \ @@ -75,6 +77,7 @@ HEADERS += qcocoaintegration.h \ qcocoasystemtrayicon.h \ qcocoaintrospection.h \ qcocoakeymapper.h \ + messages.h RESOURCES += qcocoaresources.qrc diff --git a/src/plugins/platforms/cocoa/messages.cpp b/src/plugins/platforms/cocoa/messages.cpp new file mode 100644 index 0000000000..3db1618a50 --- /dev/null +++ b/src/plugins/platforms/cocoa/messages.cpp @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins 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 "messages.h" + +#include + +// Translatable messages should go into this .cpp file for them to be picked up by lupdate. + +QT_BEGIN_NAMESPACE + +QString msgAboutQt() +{ + return QCoreApplication::translate("QCocoaMenuItem", "About Qt"); +} + +static const char *application_menu_strings[] = +{ + QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Services"), + QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Hide %1"), + QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Hide Others"), + QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Show All"), + QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Preferences..."), + QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Quit %1"), + QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","About %1") +}; + +QString qt_mac_applicationmenu_string(int type) +{ + QString menuString = QString::fromLatin1(application_menu_strings[type]); + const QString translated = QCoreApplication::translate("QMenuBar", application_menu_strings[type]); + if (translated != menuString) { + return translated; + } else { + return QCoreApplication::translate("MAC_APPLICATION_MENU", application_menu_strings[type]); + } +} + +QPlatformMenuItem::MenuRole detectMenuRole(const QString &caption) +{ + const QString aboutString = QCoreApplication::translate("QCocoaMenuItem", "About"); + if (caption.startsWith(aboutString, Qt::CaseInsensitive) || caption.endsWith(aboutString, Qt::CaseInsensitive)) + return QPlatformMenuItem::AboutRole; + if (caption.startsWith(QCoreApplication::translate("QCocoaMenuItem", "Config"), Qt::CaseInsensitive) + || caption.startsWith(QCoreApplication::translate("QCocoaMenuItem", "Preference"), Qt::CaseInsensitive) + || caption.startsWith(QCoreApplication::translate("QCocoaMenuItem", "Options"), Qt::CaseInsensitive) + || caption.startsWith(QCoreApplication::translate("QCocoaMenuItem", "Setting"), Qt::CaseInsensitive) + || caption.startsWith(QCoreApplication::translate("QCocoaMenuItem", "Setup"), Qt::CaseInsensitive)) { + return QPlatformMenuItem::PreferencesRole; + } + if (caption.startsWith(QCoreApplication::translate("QCocoaMenuItem", "Quit"), Qt::CaseInsensitive) + || caption.startsWith(QCoreApplication::translate("QCocoaMenuItem", "Exit"), Qt::CaseInsensitive)) { + return QPlatformMenuItem::QuitRole; + } + return QPlatformMenuItem::NoRole; +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/messages.h b/src/plugins/platforms/cocoa/messages.h new file mode 100644 index 0000000000..09705c1e21 --- /dev/null +++ b/src/plugins/platforms/cocoa/messages.h @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins 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 MESSAGES_H +#define MESSAGES_H + +#include +#include + +QT_BEGIN_NAMESPACE + +QString msgAboutQt(); + +QString qt_mac_applicationmenu_string(int type); + +QPlatformMenuItem::MenuRole detectMenuRole(const QString &caption); + +QT_END_NAMESPACE + +#endif // MESSAGES_H diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm index 350ef8a16a..2a17ea3dec 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm +++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm @@ -42,6 +42,7 @@ #include "qcocoamenuitem.h" #include "qcocoamenu.h" +#include "messages.h" #include "qcocoahelpers.h" #include "qcocoaautoreleasepool.h" #include "qt_mac_p.h" @@ -209,28 +210,24 @@ NSMenuItem *QCocoaMenuItem::sync() case PreferencesRole: mergeItem = [loader preferencesMenuItem]; break; - case TextHeuristicRole: { - QString aboutString = tr("About").toLower(); - if (m_text.startsWith(aboutString, Qt::CaseInsensitive) - || m_text.endsWith(aboutString, Qt::CaseInsensitive)) - { + case TextHeuristicRole: + switch (detectMenuRole(m_text)) { + case QPlatformMenuItem::AboutRole: if (m_text.indexOf(QRegExp(QString::fromLatin1("qt$"), Qt::CaseInsensitive)) == -1) mergeItem = [loader aboutMenuItem]; else mergeItem = [loader aboutQtMenuItem]; - } else if (m_text.startsWith(tr("Config"), Qt::CaseInsensitive) - || m_text.startsWith(tr("Preference"), Qt::CaseInsensitive) - || m_text.startsWith(tr("Options"), Qt::CaseInsensitive) - || m_text.startsWith(tr("Setting"), Qt::CaseInsensitive) - || m_text.startsWith(tr("Setup"), Qt::CaseInsensitive)) { + break; + case QPlatformMenuItem::PreferencesRole: mergeItem = [loader preferencesMenuItem]; - } else if (m_text.startsWith(tr("Quit"), Qt::CaseInsensitive) - || m_text.startsWith(tr("Exit"), Qt::CaseInsensitive)) { + break; + case QPlatformMenuItem::QuitRole: mergeItem = [loader quitMenuItem]; + break; + default: + break; } - break; - } default: qWarning() << Q_FUNC_INFO << "unsupported role" << (int) m_role; @@ -323,7 +320,7 @@ QString QCocoaMenuItem::mergeText() return qt_mac_applicationmenu_string(6).arg(qt_mac_applicationName()); } else if (m_native== [loader aboutQtMenuItem]) { if (m_text == QString("About Qt")) - return tr("About Qt"); + return msgAboutQt(); else return m_text; } else if (m_native == [loader preferencesMenuItem]) { diff --git a/src/plugins/platforms/cocoa/qcocoamenuloader.mm b/src/plugins/platforms/cocoa/qcocoamenuloader.mm index 726fe5c6d2..4fb7969ff4 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuloader.mm +++ b/src/plugins/platforms/cocoa/qcocoamenuloader.mm @@ -41,6 +41,7 @@ #include "qcocoamenuloader.h" +#include "messages.h" #include "qcocoahelpers.h" #include "qcocoamenubar.h" #include "qcocoamenuitem.h" @@ -57,30 +58,6 @@ QT_FORWARD_DECLARE_CLASS(QString) QT_BEGIN_NAMESPACE -#ifndef QT_NO_TRANSLATION -static const char *application_menu_strings[] = { - QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Services"), - QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Hide %1"), - QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Hide Others"), - QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Show All"), - QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Preferences..."), - QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Quit %1"), - QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","About %1") - }; - -QString qt_mac_applicationmenu_string(int type) -{ - QString menuString = QString::fromLatin1(application_menu_strings[type]); - QString translated = qApp->translate("QMenuBar", application_menu_strings[type]); - if (translated != menuString) { - return translated; - } else { - return qApp->translate("MAC_APPLICATION_MENU", - application_menu_strings[type]); - } -} -#endif - /* Loads and instantiates the main app menu from the menu nib file(s). -- cgit v1.2.3 From 146658a10f290603470b800d71b778239e764312 Mon Sep 17 00:00:00 2001 From: Jan Arve Saether Date: Tue, 23 Apr 2013 15:04:26 +0200 Subject: Fixed QLayout::addChildLayout(QLayout *l) when l had a parent Previously if l had a parent, addChildLayout would warn and skip the reparenting, but it would still add the sub layout to the layout. This caused some inconsistencies in the hierarchy which in worst case could cause crashes. Task-number: QTBUG-30758 Change-Id: I618ec3341636b97bd71e421201b22c746dcf43e1 Reviewed-by: Paul Olav Tvete --- src/widgets/kernel/qboxlayout.cpp | 3 ++- src/widgets/kernel/qformlayout.cpp | 4 ++-- src/widgets/kernel/qgridlayout.cpp | 6 ++++-- src/widgets/kernel/qlayout.cpp | 10 ++++++++++ src/widgets/kernel/qlayout.h | 1 + .../widgets/kernel/qboxlayout/tst_qboxlayout.cpp | 21 +++++++++++++++++++++ 6 files changed, 40 insertions(+), 5 deletions(-) diff --git a/src/widgets/kernel/qboxlayout.cpp b/src/widgets/kernel/qboxlayout.cpp index e1a7903628..d0e7a16999 100644 --- a/src/widgets/kernel/qboxlayout.cpp +++ b/src/widgets/kernel/qboxlayout.cpp @@ -942,7 +942,8 @@ void QBoxLayout::insertSpacerItem(int index, QSpacerItem *spacerItem) void QBoxLayout::insertLayout(int index, QLayout *layout, int stretch) { Q_D(QBoxLayout); - addChildLayout(layout); + if (!adoptLayout(layout)) + return; if (index < 0) // append index = d->list.count(); QBoxLayoutItem *it = new QBoxLayoutItem(layout, stretch); diff --git a/src/widgets/kernel/qformlayout.cpp b/src/widgets/kernel/qformlayout.cpp index e2d25de537..669faac4f6 100644 --- a/src/widgets/kernel/qformlayout.cpp +++ b/src/widgets/kernel/qformlayout.cpp @@ -976,8 +976,8 @@ void QFormLayoutPrivate::setLayout(int row, QFormLayout::ItemRole role, QLayout { if (layout) { Q_Q(QFormLayout); - q->addChildLayout(layout); - setItem(row, role, layout); + if (q->adoptLayout(layout)) + setItem(row, role, layout); } } diff --git a/src/widgets/kernel/qgridlayout.cpp b/src/widgets/kernel/qgridlayout.cpp index 12049f3303..96820e3891 100644 --- a/src/widgets/kernel/qgridlayout.cpp +++ b/src/widgets/kernel/qgridlayout.cpp @@ -1505,7 +1505,8 @@ void QGridLayout::addWidget(QWidget *widget, int fromRow, int fromColumn, void QGridLayout::addLayout(QLayout *layout, int row, int column, Qt::Alignment alignment) { Q_D(QGridLayout); - addChildLayout(layout); + if (!adoptLayout(layout)) + return; QGridBox *b = new QGridBox(layout); b->setAlignment(alignment); d->add(b, row, column); @@ -1524,7 +1525,8 @@ void QGridLayout::addLayout(QLayout *layout, int row, int column, int rowSpan, int columnSpan, Qt::Alignment alignment) { Q_D(QGridLayout); - addChildLayout(layout); + if (!adoptLayout(layout)) + return; QGridBox *b = new QGridBox(layout); b->setAlignment(alignment); d->add(b, row, (rowSpan < 0) ? -1 : row + rowSpan - 1, column, (columnSpan < 0) ? -1 : column + columnSpan - 1); diff --git a/src/widgets/kernel/qlayout.cpp b/src/widgets/kernel/qlayout.cpp index d59a9db75d..0402f9939a 100644 --- a/src/widgets/kernel/qlayout.cpp +++ b/src/widgets/kernel/qlayout.cpp @@ -806,6 +806,16 @@ void QLayout::addChildLayout(QLayout *l) } +/*! + \internal + */ +bool QLayout::adoptLayout(QLayout *layout) +{ + const bool ok = !layout->parent(); + addChildLayout(layout); + return ok; +} + #ifdef QT_DEBUG static bool layoutDebug() { diff --git a/src/widgets/kernel/qlayout.h b/src/widgets/kernel/qlayout.h index c293939bd3..6f43c2b28a 100644 --- a/src/widgets/kernel/qlayout.h +++ b/src/widgets/kernel/qlayout.h @@ -148,6 +148,7 @@ protected: void childEvent(QChildEvent *e); void addChildLayout(QLayout *l); void addChildWidget(QWidget *w); + bool adoptLayout(QLayout *layout); QRect alignmentRect(const QRect&) const; protected: diff --git a/tests/auto/widgets/kernel/qboxlayout/tst_qboxlayout.cpp b/tests/auto/widgets/kernel/qboxlayout/tst_qboxlayout.cpp index 227a31b10d..84d796f657 100644 --- a/tests/auto/widgets/kernel/qboxlayout/tst_qboxlayout.cpp +++ b/tests/auto/widgets/kernel/qboxlayout/tst_qboxlayout.cpp @@ -68,6 +68,7 @@ public slots: private slots: void insertSpacerItem(); + void insertLayout(); void sizeHint(); void sizeConstraints(); void setGeometry(); @@ -166,6 +167,26 @@ void tst_QBoxLayout::insertSpacerItem() window->show(); } +void tst_QBoxLayout::insertLayout() +{ + QWidget *window = new QWidget; + QVBoxLayout *vbox = new QVBoxLayout(window); + QVBoxLayout *dummyParentLayout = new QVBoxLayout; + QHBoxLayout *subLayout = new QHBoxLayout; + dummyParentLayout->addLayout(subLayout); + QCOMPARE(subLayout->parent(), dummyParentLayout); + QCOMPARE(dummyParentLayout->count(), 1); + + // add subLayout to another layout + QTest::ignoreMessage(QtWarningMsg, "QLayout::addChildLayout: layout \"\" already has a parent"); + vbox->addLayout(subLayout); + QCOMPARE((subLayout->parent() == vbox), (vbox->count() == 1)); + + delete dummyParentLayout; + delete window; +} + + void tst_QBoxLayout::sizeHint() { QWidget *window = new QWidget; -- cgit v1.2.3 From 1f6ab6a661a468dc6b5fb2dc24b05148e052c858 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Tue, 23 Apr 2013 10:03:48 +0200 Subject: Fixed QGLWidget not being able to be made current with a context. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the QGLWidget's creation is triggered by a sibling or similar being created it would end up without the surface type OpenGLSurface. We need to make sure the QWindow has the correct surface type to prevent QOpenGLContext::makeCurrent() from failing. Task-number: QTBUG-30811 Change-Id: Ifc85f9120d89bd0bed4a3911233799830cb3a0f3 Reviewed-by: Jørgen Lind --- src/gui/kernel/qopenglcontext.cpp | 2 +- src/opengl/qgl_qpa.cpp | 13 +++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp index 483baf0f09..c93752c3d7 100644 --- a/src/gui/kernel/qopenglcontext.cpp +++ b/src/gui/kernel/qopenglcontext.cpp @@ -759,7 +759,7 @@ bool QOpenGLContext::makeCurrent(QSurface *surface) return false; if (surface->surfaceType() != QSurface::OpenGLSurface) { - qWarning() << "QOpenGLContext::makeCurrent() called with non-opengl surface"; + qWarning() << "QOpenGLContext::makeCurrent() called with non-opengl surface" << surface; return false; } diff --git a/src/opengl/qgl_qpa.cpp b/src/opengl/qgl_qpa.cpp index 0a24654624..f3388ee5ef 100644 --- a/src/opengl/qgl_qpa.cpp +++ b/src/opengl/qgl_qpa.cpp @@ -146,10 +146,15 @@ bool QGLContext::chooseContext(const QGLContext* shareContext) if (widget->testAttribute(Qt::WA_TranslucentBackground)) winFormat.setAlphaBufferSize(qMax(winFormat.alphaBufferSize(), 8)); - if (!widget->windowHandle()->handle()) { - widget->windowHandle()->setSurfaceType(QWindow::OpenGLSurface); - widget->windowHandle()->setFormat(winFormat); - widget->winId();//make window + QWindow *window = widget->windowHandle(); + if (!window->handle() + || window->surfaceType() != QWindow::OpenGLSurface + || window->requestedFormat() != winFormat) + { + window->setSurfaceType(QWindow::OpenGLSurface); + window->setFormat(winFormat); + window->destroy(); + window->create(); } if (d->ownContext) -- cgit v1.2.3 From f2fa65e4bfa09da6e857cd8c333eec5b1a87d318 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Mon, 22 Apr 2013 13:50:18 +0200 Subject: Cocoa: Add setAlertState(), isAlertState(), beep() functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also, fix operator precedence error in QApplication::alert(). Change-Id: I140ccfba29638d24bc1c97f5f9a9611f66eb6b8f Reviewed-by: Friedemann Kleint Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoanativeinterface.h | 2 ++ src/plugins/platforms/cocoa/qcocoanativeinterface.mm | 5 +++++ src/plugins/platforms/cocoa/qcocoawindow.h | 5 +++++ src/plugins/platforms/cocoa/qcocoawindow.mm | 18 ++++++++++++++++++ src/widgets/kernel/qapplication_qpa.cpp | 2 +- 5 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.h b/src/plugins/platforms/cocoa/qcocoanativeinterface.h index ca84312059..c344ebc42c 100644 --- a/src/plugins/platforms/cocoa/qcocoanativeinterface.h +++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.h @@ -65,6 +65,8 @@ public: NativeResourceForIntegrationFunction nativeResourceFunctionForIntegration(const QByteArray &resource) Q_DECL_OVERRIDE; + Q_INVOKABLE void beep(); + static void *cglContextForContext(QOpenGLContext *context); static void *nsOpenGLContextForContext(QOpenGLContext* context); diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm index 84261ad273..daceb1e8ad 100644 --- a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm +++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm @@ -124,6 +124,11 @@ QPlatformNativeInterface::NativeResourceForIntegrationFunction QCocoaNativeInter return 0; } +void QCocoaNativeInterface::beep() +{ + NSBeep(); +} + QPlatformPrinterSupport *QCocoaNativeInterface::createPlatformPrinterSupport() { #ifndef QT_NO_WIDGETS diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h index e1de5f0add..ff7f99f96a 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.h +++ b/src/plugins/platforms/cocoa/qcocoawindow.h @@ -106,6 +106,8 @@ public: void setWindowTitle(const QString &title); void setWindowFilePath(const QString &filePath); void setWindowIcon(const QIcon &icon); + void setAlertState(bool enabled); + bool isAlertState() const; void raise(); void lower(); bool isExposed() const; @@ -190,6 +192,9 @@ public: // for QNSView bool m_frameStrutEventsEnabled; bool m_isExposed; int m_registerTouchCount; + + static const int NoAlertRequest; + NSInteger m_alertRequest; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index e726c1e4fd..e3cd791930 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -188,6 +188,8 @@ static bool isMouseEvent(NSEvent *ev) @end +const int QCocoaWindow::NoAlertRequest = -1; + QCocoaWindow::QCocoaWindow(QWindow *tlw) : QPlatformWindow(tlw) , m_nsWindow(0) @@ -202,6 +204,7 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw) , m_frameStrutEventsEnabled(false) , m_isExposed(false) , m_registerTouchCount(0) + , m_alertRequest(NoAlertRequest) { #ifdef QT_COCOA_ENABLE_WINDOW_DEBUG qDebug() << "QCocoaWindow::QCocoaWindow" << this; @@ -496,6 +499,21 @@ void QCocoaWindow::setWindowIcon(const QIcon &icon) } } +void QCocoaWindow::setAlertState(bool enabled) +{ + if (m_alertRequest == NoAlertRequest && enabled) { + m_alertRequest = [NSApp requestUserAttention:NSCriticalRequest]; + } else if (m_alertRequest != NoAlertRequest && !enabled) { + [NSApp cancelUserAttentionRequest:m_alertRequest]; + m_alertRequest = NoAlertRequest; + } +} + +bool QCocoaWindow::isAlertState() const +{ + return m_alertRequest != NoAlertRequest; +} + void QCocoaWindow::raise() { //qDebug() << "raise" << this; diff --git a/src/widgets/kernel/qapplication_qpa.cpp b/src/widgets/kernel/qapplication_qpa.cpp index 6567ef5c2f..2761c84a8d 100644 --- a/src/widgets/kernel/qapplication_qpa.cpp +++ b/src/widgets/kernel/qapplication_qpa.cpp @@ -415,7 +415,7 @@ void QApplication::beep() void QApplication::alert(QWidget *widget, int duration) { if (widget) { - if (widget->window()->isActiveWindow()&& !widget->window()->windowState() & Qt::WindowMinimized) + if (widget->window()->isActiveWindow() && !(widget->window()->windowState() & Qt::WindowMinimized)) return; if (QWindow *window= QApplicationPrivate::windowForWidget(widget)) window->alert(duration); -- cgit v1.2.3 From 56cc59110a437658b8f0b6113834fd0ca157e448 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Tue, 23 Apr 2013 14:29:56 +0200 Subject: Don't crash on a null window pointer. Task-number: QTBUG-30731 Change-Id: Id256b915012b43d1eb85bba62cbc1d42cfb58b34 Reviewed-by: Gabriel de Dietrich --- src/plugins/platforms/cocoa/qcocoanativeinterface.mm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm index daceb1e8ad..64e2b619c1 100644 --- a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm +++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm @@ -231,6 +231,9 @@ void QCocoaNativeInterface::setWindowContentView(QPlatformWindow *window, void * void QCocoaNativeInterface::registerTouchWindow(QWindow *window, bool enable) { + if (!window) + return; + // Make sure the QCocoaWindow is created when enabling. Disabling might // happen on window destruction, don't (re)create the QCocoaWindow then. if (enable) -- cgit v1.2.3 From 38bf6da7ddaa6975ea00c27144fcbc70c789d398 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Tue, 23 Apr 2013 17:05:08 +0200 Subject: Cocoa: Fix disabled minimize button on main windows Task-number: QTBUG-30775 Change-Id: Idec64f2cc6181e6889498171ead676d33c66e537 Reviewed-by: Jens Bache-Wiig Reviewed-by: Shawn Rutledge --- src/plugins/platforms/cocoa/qcocoawindow.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index e3cd791930..5cfcec8e54 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -406,7 +406,7 @@ NSUInteger QCocoaWindow::windowStyleMask(Qt::WindowFlags flags) Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint; if (flags == Qt::Window) { styleMask = (NSResizableWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSTitledWindowMask); - } else if (flags & Qt::Dialog) { + } else if ((flags & Qt::Dialog) == Qt::Dialog) { if (window()->modality() == Qt::NonModal) styleMask = NSResizableWindowMask | NSClosableWindowMask | NSTitledWindowMask; else -- cgit v1.2.3 From 32629676b977d98e853fc6101a63c0d888ff5598 Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 22 Apr 2013 08:34:53 +0200 Subject: Use a QVector instead of an array in QFileInfoPrivate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since QDateTime is pimpled, default allocation is expensive and regularly shows up in profiles of code using QFileInfo. For Qt 6, QDateTime's data members should be put into the class proper, and this change here reverted. Change-Id: I94a50e467b12772e1076181eb2ac6031984d8802 Reviewed-by: Thorbjørn Lindeijer Reviewed-by: Stephen Kelly --- src/corelib/io/qfileinfo.cpp | 2 ++ src/corelib/io/qfileinfo_p.h | 8 +++++++- src/corelib/tools/qdatetime.h | 4 ++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp index 7fcb4154f2..addcd772ab 100644 --- a/src/corelib/io/qfileinfo.cpp +++ b/src/corelib/io/qfileinfo.cpp @@ -187,6 +187,8 @@ uint QFileInfoPrivate::getFileFlags(QAbstractFileEngine::FileFlags request) cons QDateTime &QFileInfoPrivate::getFileTime(QAbstractFileEngine::FileTime request) const { Q_ASSERT(fileEngine); // should never be called when using the native FS + if (fileTimes.size() != 3) + fileTimes.resize(3); if (!cache_enabled) clearFlags(); uint cf; diff --git a/src/corelib/io/qfileinfo_p.h b/src/corelib/io/qfileinfo_p.h index 1b254f6e85..442e6b5ef0 100644 --- a/src/corelib/io/qfileinfo_p.h +++ b/src/corelib/io/qfileinfo_p.h @@ -58,6 +58,7 @@ #include "qatomic.h" #include "qshareddata.h" #include "qfilesystemengine_p.h" +#include "qvector.h" #include #include @@ -152,7 +153,12 @@ public: bool cache_enabled : 1; mutable uint fileFlags; mutable qint64 fileSize; - mutable QDateTime fileTimes[3]; + // ### Qt6: FIXME: This vector is essentially a plain array + // mutable QDateTime fileTimes[3], but the array is slower + // to initialize than the QVector as QDateTime has a pimpl. + // In Qt 6, QDateTime should inline its data members, + // and this here can be an array again. + mutable QVector fileTimes; inline bool getCachedFlag(uint c) const { return cache_enabled ? (cachedFlags & c) : 0; } inline void setCachedFlag(uint c) const diff --git a/src/corelib/tools/qdatetime.h b/src/corelib/tools/qdatetime.h index d1cc10c877..5c1668033c 100644 --- a/src/corelib/tools/qdatetime.h +++ b/src/corelib/tools/qdatetime.h @@ -262,6 +262,10 @@ public: private: friend class QDateTimePrivate; void detach(); + + // ### Qt6: Using a private here has high impact on runtime + // on users such as QFileInfo. In Qt 6, the data members + // should be inlined. QExplicitlySharedDataPointer d; #ifndef QT_NO_DATASTREAM -- cgit v1.2.3 From 649da796f54dd291c1b0e3c5b02a44cd34006a44 Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 23 Apr 2013 11:25:33 +0200 Subject: QDataStream: Be a bit more verbose about operator>>(char *&) This also fixes a few "sloppy" mentionings of "new" into "new []". Task-number: QTBUG-30777 Change-Id: I3f4add07777b59cd09cac97b672c73273b3b97eb Reviewed-by: Jerome Pasion --- src/corelib/io/qdatastream.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/corelib/io/qdatastream.cpp b/src/corelib/io/qdatastream.cpp index ae9b667b58..dc7387bc85 100644 --- a/src/corelib/io/qdatastream.cpp +++ b/src/corelib/io/qdatastream.cpp @@ -816,8 +816,12 @@ QDataStream &QDataStream::operator>>(double &f) Reads the '\\0'-terminated string \a s from the stream and returns a reference to the stream. - Space for the string is allocated using \c new -- the caller must - destroy it with \c{delete[]}. + The string is deserialized using \c{readBytes()}. + + Space for the string is allocated using \c{new []} -- the caller must + destroy it with \c{delete []}. + + \sa readBytes(), readRawData() */ QDataStream &QDataStream::operator>>(char *&s) @@ -831,8 +835,8 @@ QDataStream &QDataStream::operator>>(char *&s) Reads the buffer \a s from the stream and returns a reference to the stream. - The buffer \a s is allocated using \c new. Destroy it with the \c - delete[] operator. + The buffer \a s is allocated using \c{new []}. Destroy it with the + \c{delete []} operator. The \a l parameter is set to the length of the buffer. If the string read is empty, \a l is set to 0 and \a s is set to @@ -1101,7 +1105,9 @@ QDataStream &QDataStream::operator<<(double f) Writes the '\\0'-terminated string \a s to the stream and returns a reference to the stream. - The string is serialized using writeBytes(). + The string is serialized using \c{writeBytes()}. + + \sa writeBytes(), writeRawData() */ QDataStream &QDataStream::operator<<(const char *s) -- cgit v1.2.3 From adec3f4eaf06cf0f0960c481d6cbf9634ee35d66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Kundr=C3=A1t?= Date: Thu, 18 Apr 2013 00:05:05 +0200 Subject: Do not talk about `make confclean` in the top-level directory The configure script does not actually produce a "confclean" make target. Task-number: QTBUG-27735 Change-Id: Ia0f9e33e50c35cc6bb2941853e518a40fc9edaee Reviewed-by: Oswald Buddenhagen --- configure | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/configure b/configure index 55a643a4b0..9c86fa1e5d 100755 --- a/configure +++ b/configure @@ -6927,5 +6927,6 @@ else echo Qt will be installed into $QT_INSTALL_PREFIX fi echo -echo To reconfigure, run \'$MAKE confclean\' and \'configure\'. +echo Prior to reconfiguration, make sure you remove any leftovers from +echo the previous build. echo -- cgit v1.2.3 From 01cbd7e4b5ef841c9e091f54cb7ffa6bb059ac31 Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 22 Apr 2013 08:35:23 +0200 Subject: Remove QLocalePrivate::m_localeID It was only used for toUpper/toLower but always computed in the constructor, including QString::toLatin1 conversion and allocations. This needlessly slows down all other uses, including supposedly "cheap" operations QString::toDouble, or accesses inside QResourceFileEngine. The benchmarks indicates that doing it always when needed is bearable. There's still a lot of improvement potential on these code paths. Change-Id: I88b637ee11f9f7ea614f8da4ec5df0bf40664fce Reviewed-by: Konstantin Ritt --- src/corelib/tools/qlocale.cpp | 60 ++++++++-------- src/corelib/tools/qlocale_p.h | 8 +-- tests/benchmarks/corelib/tools/qlocale/main.cpp | 83 ++++++++++++++++++++++ tests/benchmarks/corelib/tools/qlocale/qlocale.pro | 5 ++ tests/benchmarks/corelib/tools/tools.pro | 1 + 5 files changed, 121 insertions(+), 36 deletions(-) create mode 100644 tests/benchmarks/corelib/tools/qlocale/main.cpp create mode 100644 tests/benchmarks/corelib/tools/qlocale/qlocale.pro diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index 4aaa1af688..b5f983899a 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -284,51 +284,51 @@ QLocaleId QLocaleId::withLikelySubtagsRemoved() const return max; } -QString QLocaleId::bcp47Name() const +QByteArray QLocaleId::name(char separator) const { if (language_id == QLocale::AnyLanguage) - return QString(); + return QByteArray(); if (language_id == QLocale::C) - return QStringLiteral("C"); + return QByteArrayLiteral("C"); - const unsigned char *lang = language_code_list + 3*uint(language_id); + const unsigned char *lang = language_code_list + 3 * language_id; const unsigned char *script = - (script_id != QLocale::AnyScript ? script_code_list + 4*uint(script_id) : 0); + (script_id != QLocale::AnyScript ? script_code_list + 4 * script_id : 0); const unsigned char *country = - (country_id != QLocale::AnyCountry ? country_code_list + 3*uint(country_id) : 0); + (country_id != QLocale::AnyCountry ? country_code_list + 3 * country_id : 0); char len = (lang[2] != 0 ? 3 : 2) + (script ? 4+1 : 0) + (country ? (country[2] != 0 ? 3 : 2)+1 : 0); - QString name(len, Qt::Uninitialized); - QChar *uc = name.data(); - *uc++ = ushort(lang[0]); - *uc++ = ushort(lang[1]); + QByteArray name(len, Qt::Uninitialized); + char *uc = name.data(); + *uc++ = lang[0]; + *uc++ = lang[1]; if (lang[2] != 0) - *uc++ = ushort(lang[2]); + *uc++ = lang[2]; if (script) { - *uc++ = QLatin1Char('-'); - *uc++ = ushort(script[0]); - *uc++ = ushort(script[1]); - *uc++ = ushort(script[2]); - *uc++ = ushort(script[3]); + *uc++ = separator; + *uc++ = script[0]; + *uc++ = script[1]; + *uc++ = script[2]; + *uc++ = script[3]; } if (country) { - *uc++ = QLatin1Char('-'); - *uc++ = ushort(country[0]); - *uc++ = ushort(country[1]); + *uc++ = separator; + *uc++ = country[0]; + *uc++ = country[1]; if (country[2] != 0) - *uc++ = ushort(country[2]); + *uc++ = country[2]; } return name; } -QString QLocalePrivate::bcp47Name() const +QByteArray QLocalePrivate::bcp47Name(char separator) const { if (m_data->m_language_id == QLocale::AnyLanguage) - return QString(); + return QByteArray(); if (m_data->m_language_id == QLocale::C) - return QStringLiteral("C"); + return QByteArrayLiteral("C"); QLocaleId localeId = QLocaleId::fromIds(m_data->m_language_id, m_data->m_script_id, m_data->m_country_id); - return localeId.withLikelySubtagsRemoved().bcp47Name(); + return localeId.withLikelySubtagsRemoved().name(separator); } const QLocaleData *QLocaleData::findLocaleData(QLocale::Language language, QLocale::Script script, QLocale::Country country) @@ -1080,7 +1080,7 @@ QString QLocale::name() const */ QString QLocale::bcp47Name() const { - return d->bcp47Name(); + return QString::fromLatin1(d->bcp47Name()); } /*! @@ -2494,7 +2494,7 @@ QString QLocale::toUpper(const QString &str) const { #ifdef QT_USE_ICU bool ok = true; - QString result = QIcu::toUpper(d->m_localeID, str, &ok); + QString result = QIcu::toUpper(d->bcp47Name('_'), str, &ok); if (ok) return result; // else fall through and use Qt's toUpper @@ -2511,7 +2511,7 @@ QString QLocale::toLower(const QString &str) const { #ifdef QT_USE_ICU bool ok = true; - QString result = QIcu::toLower(d->m_localeID, str, &ok); + const QString result = QIcu::toLower(d->bcp47Name('_'), str, &ok); if (ok) return result; // else fall through and use Qt's toUpper @@ -3662,14 +3662,14 @@ QStringList QLocale::uiLanguages() const const QLocaleId min = max.withLikelySubtagsRemoved(); QStringList uiLanguages; - uiLanguages.append(min.bcp47Name()); + uiLanguages.append(QString::fromLatin1(min.name())); if (id.script_id) { id.script_id = 0; if (id != min && id.withLikelySubtagsAdded() == max) - uiLanguages.append(id.bcp47Name()); + uiLanguages.append(QString::fromLatin1(id.name())); } if (max != min && max != id) - uiLanguages.append(max.bcp47Name()); + uiLanguages.append(QString::fromLatin1(max.name())); return uiLanguages; } diff --git a/src/corelib/tools/qlocale_p.h b/src/corelib/tools/qlocale_p.h index 4c0432bba7..9674342307 100644 --- a/src/corelib/tools/qlocale_p.h +++ b/src/corelib/tools/qlocale_p.h @@ -151,7 +151,7 @@ struct QLocaleId QLocaleId withLikelySubtagsAdded() const; QLocaleId withLikelySubtagsRemoved() const; - QString bcp47Name() const; + QByteArray name(char separator = '-') const; ushort language_id, script_id, country_id; }; @@ -212,8 +212,6 @@ public: : m_index(index), m_numberOptions(numberOptions) { m_data = dataPointerForIndex(index); - m_localeID = bcp47Name().toLatin1(); - m_localeID.replace('-','_'); } ~QLocalePrivate() @@ -232,7 +230,7 @@ public: quint16 languageId() const { return m_data->m_language_id; } quint16 countryId() const { return m_data->m_country_id; } - QString bcp47Name() const; + QByteArray bcp47Name(char separator = '-') const; // ### QByteArray::fromRawData would be more optimal inline QString languageCode() const { return QLocalePrivate::languageToCode(QLocale::Language(m_data->m_language_id)); } @@ -334,11 +332,9 @@ public: QString dateTimeToString(const QString &format, const QDate *date, const QTime *time, const QLocale *q) const; - friend class QLocale; quint16 m_index; quint16 m_numberOptions; const QLocaleData *m_data; - QByteArray m_localeID; }; inline char QLocalePrivate::digitToCLocale(QChar in) const diff --git a/tests/benchmarks/corelib/tools/qlocale/main.cpp b/tests/benchmarks/corelib/tools/qlocale/main.cpp new file mode 100644 index 0000000000..c62baf556e --- /dev/null +++ b/tests/benchmarks/corelib/tools/qlocale/main.cpp @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** 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 +#include + +class tst_QLocale : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + void toUpper_QLocale_1(); + void toUpper_QLocale_2(); + void toUpper_QString(); +}; + +static QString data() +{ + return QStringLiteral("/qt-5/qtbase/tests/benchmarks/corelib/tools/qlocale"); +} + +#define LOOP(s) for (int i = 0; i < 5000; ++i) { s; } + +void tst_QLocale::toUpper_QLocale_1() +{ + QString s = data(); + QBENCHMARK { LOOP(QLocale().toUpper(s)) } +} + +void tst_QLocale::toUpper_QLocale_2() +{ + QString s = data(); + QLocale l; + QBENCHMARK { LOOP(l.toUpper(s)) } +} + +void tst_QLocale::toUpper_QString() +{ + QString s = data(); + QBENCHMARK { LOOP(s.toUpper()) } +} + +QTEST_MAIN(tst_QLocale) + +#include "main.moc" diff --git a/tests/benchmarks/corelib/tools/qlocale/qlocale.pro b/tests/benchmarks/corelib/tools/qlocale/qlocale.pro new file mode 100644 index 0000000000..9e8f2721c9 --- /dev/null +++ b/tests/benchmarks/corelib/tools/qlocale/qlocale.pro @@ -0,0 +1,5 @@ +TARGET = tst_bench_qlocale +QT = core testlib + +SOURCES += main.cpp +DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/benchmarks/corelib/tools/tools.pro b/tests/benchmarks/corelib/tools/tools.pro index 7565b1a167..ce3e75acd7 100644 --- a/tests/benchmarks/corelib/tools/tools.pro +++ b/tests/benchmarks/corelib/tools/tools.pro @@ -5,6 +5,7 @@ SUBDIRS = \ qbytearray \ qcontiguouscache \ qlist \ + qlocale \ qmap \ qrect \ qregexp \ -- cgit v1.2.3 From 3821047e6c40485a14f7173c6ded07474997820e Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Tue, 23 Apr 2013 12:22:09 +0300 Subject: Fix memory access violation The pointer returned by unicode() was deleted right afterwards. Change-Id: I7cef72386d02c7be42e71134f616926506d37ea6 Reviewed-by: Gatis Paeglis Reviewed-by: Konstantin Ritt --- .../platforminputcontexts/compose/generator/qtablegenerator.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp index 1113194136..400f7aece8 100644 --- a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp +++ b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp @@ -280,8 +280,7 @@ ushort TableGenerator::keysymToUtf8(quint32 sym) qDebug() << QString("keysym - 0x%1 : utf8 - %2").arg(QString::number(sym, 16)) .arg(codec->toUnicode(chars)); #endif - const QChar *ch = QString(chars.data()).unicode(); - return ch->unicode(); + return QString::fromUtf8(chars).at(0).unicode(); } quint32 TableGenerator::stringToKeysym(QString keysymName) -- cgit v1.2.3 From 71a1ff39bcf67117e94b669aa0ee059bf1f03b3a Mon Sep 17 00:00:00 2001 From: David Faure Date: Mon, 22 Apr 2013 16:18:58 +0200 Subject: qxcb: output clear error message when running on an 8-bit display MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, running a Qt5 widget app in Xvfb (with its default setup, 8 bit color depth) outputs a stream of error messages, starting with: QWidget::paintEngine: QWidget::paintEngine: Should no longer be called Better output clearly the reason why we end up in that method: painting on a null image, due to the unsupported image format. Maybe this should even be a qFatal... Change-Id: Iae8f1b057518c146bf8e034999c1b5e67ce6ef5e Reviewed-by: Friedemann Kleint Reviewed-by: Samuel Rødal --- src/plugins/platforms/xcb/qxcbwindow.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 68ccbfb8c0..f2ec4ce4b0 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -170,7 +170,9 @@ static inline QImage::Format imageFormatForDepth(int depth) case 32: return QImage::Format_ARGB32_Premultiplied; case 24: return QImage::Format_RGB32; case 16: return QImage::Format_RGB16; - default: return QImage::Format_Invalid; + default: + qWarning("Unsupported screen depth: %d", depth); + return QImage::Format_Invalid; } } -- cgit v1.2.3 From 1ea1abeb91f544b4cf595d229249ee859090bee5 Mon Sep 17 00:00:00 2001 From: David Faure Date: Mon, 15 Apr 2013 23:52:32 +0200 Subject: Implement startup notification spec again. This functionality was in Qt4's qapplication_x11.cpp and was missing from the XCB QPA plugin. Ported the code from xlib to xcb. This code was actually tested (with plasma), unlike the Qt-4.8 code which skipped every other character... for (uint i = 0; i < 20 && i + sent <= length; i++) xevent.xclient.data.b[i] = message[i + sent++]; Provide a QPA native-function for accessing the startup id, for cases where an application doesn't show a window, but starts another app instead, or asks a running app to show the window on its behalf. Change-Id: If392179efddd70a51c45a8fab4fb9d753913094a Reviewed-by: David Faure (KDE) --- src/plugins/platforms/xcb/qxcbconnection.cpp | 4 +++ src/plugins/platforms/xcb/qxcbconnection.h | 5 ++++ src/plugins/platforms/xcb/qxcbintegration.h | 2 ++ src/plugins/platforms/xcb/qxcbnativeinterface.cpp | 30 ++++++++++++++++++++ src/plugins/platforms/xcb/qxcbnativeinterface.h | 5 +++- src/plugins/platforms/xcb/qxcbscreen.cpp | 34 +++++++++++++++++++++++ src/plugins/platforms/xcb/qxcbscreen.h | 2 ++ src/plugins/platforms/xcb/qxcbwindow.cpp | 4 +++ 8 files changed, 85 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 1504bd99d2..cb80fdfbd3 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -344,6 +344,10 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, const char m_drag = new QXcbDrag(this); #endif + m_startupId = qgetenv("DESKTOP_STARTUP_ID"); + if (!m_startupId.isNull()) + qunsetenv("DESKTOP_STARTUP_ID"); + sync(); } diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index f69a8a9f35..8ab65fc2bc 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -388,6 +388,9 @@ public: QXcbWindow *focusWindow() const { return m_focusWindow; } void setFocusWindow(QXcbWindow *); + QByteArray startupId() const { return m_startupId; } + void clearStartupId() { m_startupId.clear(); } + private slots: void processXcbEvents(); @@ -516,6 +519,8 @@ private: Qt::MouseButtons m_buttons; QXcbWindow *m_focusWindow; + + QByteArray m_startupId; }; #define DISPLAY_FROM_XCB(object) ((Display *)(object->connection()->xlib_display())) diff --git a/src/plugins/platforms/xcb/qxcbintegration.h b/src/plugins/platforms/xcb/qxcbintegration.h index 6db9d82cca..451dc43475 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.h +++ b/src/plugins/platforms/xcb/qxcbintegration.h @@ -95,6 +95,8 @@ public: QStringList themeNames() const; QPlatformTheme *createPlatformTheme(const QString &name) const; + QXcbConnection *defaultConnection() const { return m_connections.first(); } + private: QList m_connections; diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp index 6ac69a8335..da60cfd2bd 100644 --- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp +++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp @@ -42,6 +42,7 @@ #include "qxcbnativeinterface.h" #include "qxcbscreen.h" +#include "qxcbintegration.h" #include #include @@ -78,6 +79,7 @@ public: insert("apptime",QXcbNativeInterface::AppTime); insert("appusertime",QXcbNativeInterface::AppUserTime); insert("hintstyle", QXcbNativeInterface::ScreenHintStyle); + insert("startupid", QXcbNativeInterface::StartupId); } }; @@ -99,6 +101,25 @@ void QXcbNativeInterface::beep() // For QApplication::beep() #endif } +void *QXcbNativeInterface::nativeResourceForIntegration(const QByteArray &resourceString) +{ + QByteArray lowerCaseResource = resourceString.toLower(); + if (!qXcbResourceMap()->contains(lowerCaseResource)) + return 0; + + ResourceType resource = qXcbResourceMap()->value(lowerCaseResource); + void *result = 0; + switch (resource) { + case StartupId: + result = startupId(); + break; + default: + break; + } + + return result; +} + void *QXcbNativeInterface::nativeResourceForContext(const QByteArray &resourceString, QOpenGLContext *context) { QByteArray lowerCaseResource = resourceString.toLower(); @@ -196,6 +217,15 @@ void *QXcbNativeInterface::appUserTime(const QXcbScreen *screen) return reinterpret_cast(quintptr(screen->connection()->netWmUserTime())); } +void *QXcbNativeInterface::startupId() +{ + QXcbIntegration* integration = static_cast(QGuiApplicationPrivate::platformIntegration()); + QXcbConnection *defaultConnection = integration->defaultConnection(); + if (defaultConnection) + return reinterpret_cast(const_cast(defaultConnection->startupId().constData())); + return 0; +} + void QXcbNativeInterface::setAppTime(QScreen* screen, xcb_timestamp_t time) { static_cast(screen->handle())->connection()->setTime(time); diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.h b/src/plugins/platforms/xcb/qxcbnativeinterface.h index 919a21d00d..e27bfa5a46 100644 --- a/src/plugins/platforms/xcb/qxcbnativeinterface.h +++ b/src/plugins/platforms/xcb/qxcbnativeinterface.h @@ -65,11 +65,13 @@ public: GLXContext, AppTime, AppUserTime, - ScreenHintStyle + ScreenHintStyle, + StartupId }; QXcbNativeInterface(); + void *nativeResourceForIntegration(const QByteArray &resource) Q_DECL_OVERRIDE; void *nativeResourceForContext(const QByteArray &resourceString, QOpenGLContext *context); void *nativeResourceForScreen(const QByteArray &resource, QScreen *screen); void *nativeResourceForWindow(const QByteArray &resourceString, QWindow *window); @@ -86,6 +88,7 @@ public: void *graphicsDeviceForWindow(QWindow *window); void *appTime(const QXcbScreen *screen); void *appUserTime(const QXcbScreen *screen); + void *startupId(); static void setAppTime(QScreen *screen, xcb_timestamp_t time); static void setAppUserTime(QScreen *screen, xcb_timestamp_t time); static void *eglContextForContext(QOpenGLContext *context); diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp index 38b4c873ad..a6ead49a27 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.cpp +++ b/src/plugins/platforms/xcb/qxcbscreen.cpp @@ -233,6 +233,40 @@ QWindow *QXcbScreen::topLevelAt(const QPoint &p) const return 0; } +void QXcbScreen::windowShown(QXcbWindow *window) +{ + // Freedesktop.org Startup Notification + if (!connection()->startupId().isEmpty() && window->window()->isTopLevel()) { + sendStartupMessage(QByteArrayLiteral("remove: ID=") + connection()->startupId()); + connection()->clearStartupId(); + } +} + +void QXcbScreen::sendStartupMessage(const QByteArray &message) const +{ + xcb_window_t rootWindow = root(); + + xcb_client_message_event_t ev; + ev.response_type = XCB_CLIENT_MESSAGE; + ev.format = 8; + ev.type = connection()->atom(QXcbAtom::_NET_STARTUP_INFO_BEGIN); + ev.window = rootWindow; + int sent = 0; + int length = message.length() + 1; // include NUL byte + const char *data = message.constData(); + do { + if (sent == 20) + ev.type = connection()->atom(QXcbAtom::_NET_STARTUP_INFO); + + const int start = sent; + const int numBytes = qMin(length - start, 20); + memcpy(ev.data.data8, data + start, numBytes); + xcb_send_event(connection()->xcb_connection(), false, rootWindow, XCB_EVENT_MASK_PROPERTY_CHANGE, (const char *) &ev); + + sent += numBytes; + } while (sent < length); +} + const xcb_visualtype_t *QXcbScreen::visualForId(xcb_visualid_t visualid) const { QMap::const_iterator it = m_visuals.find(visualid); diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h index c3b13fd1ea..0382be8a29 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.h +++ b/src/plugins/platforms/xcb/qxcbscreen.h @@ -87,6 +87,7 @@ public: xcb_window_t clientLeader() const { return m_clientLeader; } + void windowShown(QXcbWindow *window); QString windowManagerName() const { return m_windowManagerName; } bool syncRequestSupported() const { return m_syncRequestSupported; } @@ -105,6 +106,7 @@ private: static bool xResource(const QByteArray &identifier, const QByteArray &expectedIdentifier, int *value); + void sendStartupMessage(const QByteArray &message) const; xcb_screen_t *m_screen; xcb_randr_crtc_t m_crtc; diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index f2ec4ce4b0..4090758d36 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -46,6 +46,7 @@ #include #include +#include "qxcbintegration.h" #include "qxcbconnection.h" #include "qxcbscreen.h" #include "qxcbdrag.h" @@ -653,6 +654,9 @@ void QXcbWindow::show() updateNetWmUserTime(connection()->time()); Q_XCB_CALL(xcb_map_window(xcb_connection(), m_window)); + + m_screen->windowShown(this); + xcb_flush(xcb_connection()); connection()->sync(); -- cgit v1.2.3 From e0cf3fcd8f8680e9c8b0fe1f1f18c1dda89eca80 Mon Sep 17 00:00:00 2001 From: Thomas McGuire Date: Tue, 23 Apr 2013 09:37:29 +0200 Subject: Fix retrieving of the generic system proxy via environment variables ignoreProxyFor() always returned true if the no_proxy was not set, which resulted in the first token being an empty QByteArray, causing the endsWith() check to always evaluate to true. Add a unit test that is enabled for those platforms that use the generic system proxy. Change-Id: I6081ad5e0b8e2c3fee1568835907c32bde5b7772 Reviewed-by: Peter Hartmann --- src/network/kernel/qnetworkproxy_generic.cpp | 6 +++- .../tst_qnetworkproxyfactory.cpp | 41 ++++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/network/kernel/qnetworkproxy_generic.cpp b/src/network/kernel/qnetworkproxy_generic.cpp index 9069755da4..c576719076 100644 --- a/src/network/kernel/qnetworkproxy_generic.cpp +++ b/src/network/kernel/qnetworkproxy_generic.cpp @@ -55,7 +55,11 @@ QT_BEGIN_NAMESPACE static bool ignoreProxyFor(const QNetworkProxyQuery &query) { - const QList noProxyTokens = qgetenv("no_proxy").split(','); + const QByteArray noProxy = qgetenv("no_proxy").trimmed(); + if (noProxy.isEmpty()) + return false; + + const QList noProxyTokens = noProxy.split(','); foreach (const QByteArray &rawToken, noProxyTokens) { QByteArray token = rawToken.trimmed(); diff --git a/tests/auto/network/kernel/qnetworkproxyfactory/tst_qnetworkproxyfactory.cpp b/tests/auto/network/kernel/qnetworkproxyfactory/tst_qnetworkproxyfactory.cpp index d57a99a758..e06285dc67 100644 --- a/tests/auto/network/kernel/qnetworkproxyfactory/tst_qnetworkproxyfactory.cpp +++ b/tests/auto/network/kernel/qnetworkproxyfactory/tst_qnetworkproxyfactory.cpp @@ -87,6 +87,8 @@ private slots: void inNetworkAccessManager_data(); void inNetworkAccessManager(); #endif + void genericSystemProxy(); + void genericSystemProxy_data(); private: QString formatProxyName(const QNetworkProxy & proxy) const; @@ -367,6 +369,45 @@ void tst_QNetworkProxyFactory::inNetworkAccessManager() #endif //QT_NO_BEARERMANAGEMENT +Q_DECLARE_METATYPE(QNetworkProxy::ProxyType) + +void tst_QNetworkProxyFactory::genericSystemProxy() +{ + QFETCH(QByteArray, envVar); + QFETCH(QByteArray, url); + QFETCH(QNetworkProxy::ProxyType, proxyType); + QFETCH(QString, hostName); + 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_MAC) || defined Q_OS_IOS) + qputenv(envVar, url); + const QList systemProxy = QNetworkProxyFactory::systemProxyForQuery(); + QCOMPARE(systemProxy.size(), 1); + QCOMPARE(systemProxy.first().type(), proxyType); + QCOMPARE(systemProxy.first().hostName(), hostName); + QCOMPARE(systemProxy.first().port(), static_cast(port)); + qunsetenv(envVar); +#else + QSKIP("Generic system proxy not available on this platform."); +#endif +} + +void tst_QNetworkProxyFactory::genericSystemProxy_data() +{ + QTest::addColumn("envVar"); + QTest::addColumn("url"); + QTest::addColumn("proxyType"); + QTest::addColumn("hostName"); + QTest::addColumn("port"); + + QTest::newRow("no proxy") << QByteArray("http_proxy") << QByteArray() << QNetworkProxy::NoProxy + << QString() << 0; + QTest::newRow("socks5") << QByteArray("http_proxy") << QByteArray("socks5://127.0.0.1:4242") + << QNetworkProxy::Socks5Proxy << QString("127.0.0.1") << 4242; + QTest::newRow("http") << QByteArray("http_proxy") << QByteArray("http://example.com:666") + << QNetworkProxy::HttpProxy << QString("example.com") << 666; +} class QSPFQThread : public QThread { -- cgit v1.2.3 From 34673203788dad6817fe1aaa21ca7432a32330d3 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Tue, 23 Apr 2013 17:07:01 +0200 Subject: Don't list all QMAKE_LIBS in QMAKE_LIBS_OPENGL_ES2. There is no need to, and it confuses the generation of cmake files. Change-Id: I00c8751990e707cf32652babcb9af3e4b681561a Reviewed-by: Oswald Buddenhagen --- 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 7e78725858..d1b94bb1aa 100644 --- a/mkspecs/android-g++/qmake.conf +++ b/mkspecs/android-g++/qmake.conf @@ -179,6 +179,6 @@ QMAKE_LIBS_THREAD = QMAKE_LIBS_EGL = -lEGL QMAKE_LIBS_OPENGL = QMAKE_LIBS_OPENGL_ES1 = -lGLESv1_CM -QMAKE_LIBS_OPENGL_ES2 = -lGLESv2 $$QMAKE_LIBS +QMAKE_LIBS_OPENGL_ES2 = -lGLESv2 load(qt_config) -- cgit v1.2.3 From e145b67fbd54f147dab0f8e460280a9c8533aa7b Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Thu, 4 Apr 2013 11:30:43 +0200 Subject: SSL internals: do not write after shutting down the socket ... but rather throw an error, so the HTTP layer can recover from a SSL shutdown gracefully. In case the other side sent us a shutdown, we should not send one as well, as it results in an error. Change-Id: Ie7a56cf3008b6ead912aade18dbec67846e2a87e Reviewed-by: Richard J. Moore --- src/network/ssl/qsslsocket.cpp | 2 ++ src/network/ssl/qsslsocket_openssl.cpp | 14 ++++++++++---- src/network/ssl/qsslsocket_p.h | 1 + tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp | 3 ++- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp index a8bf8f83b8..f2310356df 100644 --- a/src/network/ssl/qsslsocket.cpp +++ b/src/network/ssl/qsslsocket.cpp @@ -1908,6 +1908,7 @@ QSslSocketPrivate::QSslSocketPrivate() , mode(QSslSocket::UnencryptedMode) , autoStartHandshake(false) , connectionEncrypted(false) + , shutdown(false) , ignoreAllSslErrors(false) , readyReadEmittedPointer(0) , allowRootCertOnDemandLoading(true) @@ -1933,6 +1934,7 @@ void QSslSocketPrivate::init() autoStartHandshake = false; connectionEncrypted = false; ignoreAllSslErrors = false; + shutdown = false; // we don't want to clear the ignoreErrorsList, so // that it is possible setting it before connecting diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index 3b2de7a05b..d515f27865 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -934,8 +934,11 @@ void QSslSocketBackendPrivate::transmit() #ifdef QSSLSOCKET_DEBUG qDebug() << "QSslSocketBackendPrivate::transmit: remote disconnect"; #endif - plainSocket->disconnectFromHost(); - break; + shutdown = true; // the other side shut down, make sure we do not send shutdown ourselves + q->setErrorString(QSslSocket::tr("The TLS/SSL connection has been closed")); + q->setSocketError(QAbstractSocket::RemoteHostClosedError); + emit q->error(QAbstractSocket::RemoteHostClosedError); + return; case SSL_ERROR_SYSCALL: // some IO error case SSL_ERROR_SSL: // error in the SSL library // we do not know exactly what the error is, nor whether we can recover from it, @@ -1369,8 +1372,11 @@ void QWindowsCaRootFetcher::start() void QSslSocketBackendPrivate::disconnectFromHost() { if (ssl) { - q_SSL_shutdown(ssl); - transmit(); + if (!shutdown) { + q_SSL_shutdown(ssl); + shutdown = true; + transmit(); + } } plainSocket->disconnectFromHost(); } diff --git a/src/network/ssl/qsslsocket_p.h b/src/network/ssl/qsslsocket_p.h index 72117353ac..d1d79ae09c 100644 --- a/src/network/ssl/qsslsocket_p.h +++ b/src/network/ssl/qsslsocket_p.h @@ -109,6 +109,7 @@ public: QSslSocket::SslMode mode; bool autoStartHandshake; bool connectionEncrypted; + bool shutdown; bool ignoreAllSslErrors; QList ignoreErrorsList; bool* readyReadEmittedPointer; diff --git a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp index feb6978690..f3adb2b52f 100644 --- a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp +++ b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp @@ -2135,7 +2135,8 @@ void tst_QSslSocket::writeBigChunk() QFAIL("Error while writing! Check if the OpenSSL BIO size is limited?!"); } // also check the error string. If another error (than UnknownError) occurred, it should be different than before - QVERIFY(errorBefore == errorAfter); + QVERIFY2(errorBefore == errorAfter || socket->error() == QAbstractSocket::RemoteHostClosedError, + QByteArray("unexpected error: ").append(qPrintable(errorAfter))); // check that everything has been written to OpenSSL QVERIFY(socket->bytesToWrite() == 0); -- cgit v1.2.3 From 4341ae32f43e7e36a92c6e738a29de40d0667cb0 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Mon, 22 Apr 2013 21:42:52 +0200 Subject: Enable OpenGL library detection for mac. Change-Id: If99d3faf2b08ac5109d619ff69efdaa3857c007f Reviewed-by: Stephen Kelly --- src/gui/Qt5GuiConfigExtras.cmake.in | 7 +++---- tests/auto/cmake/CMakeLists.txt | 8 +++----- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/gui/Qt5GuiConfigExtras.cmake.in b/src/gui/Qt5GuiConfigExtras.cmake.in index 03b98ed273..f385fa0f6e 100644 --- a/src/gui/Qt5GuiConfigExtras.cmake.in +++ b/src/gui/Qt5GuiConfigExtras.cmake.in @@ -1,6 +1,4 @@ -!!IF !mac - !!IF !isEmpty(CMAKE_ANGLE_EGL_DLL_RELEASE) !!IF isEmpty(CMAKE_INCLUDE_DIR_IS_ABSOLUTE) @@ -73,6 +71,9 @@ macro(_qt5gui_find_extra_libs Name Libs LibDir IncDirs) PATHS \"${LibDir}\" NO_DEFAULT_PATH !!ENDIF ) +!!IF mac + set(Qt5Gui_${_cmake_lib_name}_LIBRARY "${Qt5Gui_${_cmake_lib_name}_LIBRARY}/${_lib}") +!!ENDIF if (NOT Qt5Gui_${_cmake_lib_name}_LIBRARY) message(FATAL_ERROR \"Failed to find \\\"${_lib}\\\" in \\\"${LibDir}\\\", using the CMAKE_FIND_ROOT_PATH \\\"${CMAKE_FIND_ROOT_PATH}\\\".\") endif() @@ -123,5 +124,3 @@ foreach(_config ${_configs}) ) endforeach() unset(_configs) - -!!ENDIF diff --git a/tests/auto/cmake/CMakeLists.txt b/tests/auto/cmake/CMakeLists.txt index ea218f630f..04e73cc7c9 100644 --- a/tests/auto/cmake/CMakeLists.txt +++ b/tests/auto/cmake/CMakeLists.txt @@ -121,12 +121,10 @@ test_module_includes( ) expect_pass(test_concurrent_module) expect_pass(test_openglextensions_module) -if (NOT APPLE) - if (QT_WITH_ANGLE OR NOT WIN32) - expect_pass(test_egl_lib) - endif() - expect_pass(test_opengl_lib) +if (QT_WITH_ANGLE OR (NOT WIN32 AND NOT APPLE)) + expect_pass(test_egl_lib) endif() +expect_pass(test_opengl_lib) if (NOT CMAKE_VERSION VERSION_LESS 2.8.11) expect_pass(test_interface) -- cgit v1.2.3 From af35ee291a1bbbc8627f9a17f7e104898d49b138 Mon Sep 17 00:00:00 2001 From: Mark Brand Date: Tue, 23 Apr 2013 22:46:43 +0200 Subject: qsql_odbc: fix SQLGetStmtAtt usage Failure to initialize the variable can cause spurious non-zero values. http://msdn.microsoft.com/en-us/library/windows/desktop/ms715438(v=vs.85).aspx "..value can either be a SQLULEN value or a null-terminated character string. If the value is a SQLULEN value, some drivers may only write the lower 32-bit or 16-bit of a buffer and leave the higher-order bit unchanged. Therefore, applications should use a buffer of SQLULEN and initialize the value to 0 before calling this function. Also, the BufferLength and StringLengthPtr arguments are not used." Follow-up to 1509316a37fb2d365230d020d1dfc251c830fd56 Change-Id: I2e92eb845a2590bea0849c52bde8902adff1b419 Reviewed-by: Andy Shaw --- src/sql/drivers/odbc/qsql_odbc.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/sql/drivers/odbc/qsql_odbc.cpp b/src/sql/drivers/odbc/qsql_odbc.cpp index d36a224d8e..77accc6e9d 100644 --- a/src/sql/drivers/odbc/qsql_odbc.cpp +++ b/src/sql/drivers/odbc/qsql_odbc.cpp @@ -958,9 +958,8 @@ bool QODBCResult::reset (const QString& query) return false; } - SQLINTEGER bufferLength; - SQLULEN isScrollable; - r = SQLGetStmtAttr(d->hStmt, SQL_ATTR_CURSOR_SCROLLABLE, &isScrollable, SQL_IS_INTEGER, &bufferLength); + SQLULEN isScrollable = 0; + r = SQLGetStmtAttr(d->hStmt, SQL_ATTR_CURSOR_SCROLLABLE, &isScrollable, SQL_IS_INTEGER, 0); if(r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) QSqlResult::setForwardOnly(isScrollable==SQL_NONSCROLLABLE); @@ -1106,7 +1105,7 @@ bool QODBCResult::fetchLast() "Unable to fetch last"), QSqlError::ConnectionError, d)); return false; } - SQLINTEGER currRow; + SQLULEN currRow = 0; r = SQLGetStmtAttr(d->hStmt, SQL_ROW_NUMBER, &currRow, @@ -1592,9 +1591,8 @@ bool QODBCResult::exec() return false; } - SQLINTEGER bufferLength; - SQLULEN isScrollable; - r = SQLGetStmtAttr(d->hStmt, SQL_ATTR_CURSOR_SCROLLABLE, &isScrollable, SQL_IS_INTEGER, &bufferLength); + SQLULEN isScrollable = 0; + r = SQLGetStmtAttr(d->hStmt, SQL_ATTR_CURSOR_SCROLLABLE, &isScrollable, SQL_IS_INTEGER, 0); if(r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) QSqlResult::setForwardOnly(isScrollable==SQL_NONSCROLLABLE); -- cgit v1.2.3 From 9d7fe3eb3dcb71926b3db65df835d45fc431eebb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Tue, 23 Apr 2013 08:41:08 +0200 Subject: Fixed crashes relating to SVG icons. Creating a second QFactoryLoader for the same plugins seems to trigger an unload of the plugins loaded by the first factory loader. The QIconEngine created by the SVG icon plugin thus gets an invalid virtual table pointer, which causes a crash when attempting to call any virtual function in the QIconEngine (pixmap(), the virtual destructor, etc). Reusing a single QFactoryLoader instead fixes the crash. Task-number: QTBUG-30496 Change-Id: I80c5fa8b52ab9b0db68499f8c37fad14a1ac4f3c Reviewed-by: Friedemann Kleint --- src/gui/image/qicon.cpp | 5 +++++ src/gui/image/qiconloader.cpp | 9 +++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp index d73cd0aa57..45eda78397 100644 --- a/src/gui/image/qicon.cpp +++ b/src/gui/image/qicon.cpp @@ -483,6 +483,11 @@ void QPixmapIconEngine::virtual_hook(int id, void *data) #ifndef QT_NO_LIBRARY Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, (QIconEngineFactoryInterface_iid, QLatin1String("/iconengines"), Qt::CaseInsensitive)) + +QFactoryLoader *qt_iconEngineFactoryLoader() +{ + return loader(); +} #endif diff --git a/src/gui/image/qiconloader.cpp b/src/gui/image/qiconloader.cpp index c2e5161bd3..105dc26c9b 100644 --- a/src/gui/image/qiconloader.cpp +++ b/src/gui/image/qiconloader.cpp @@ -104,6 +104,10 @@ static inline QStringList systemIconSearchPaths() return QStringList(); } +#ifndef QT_NO_LIBRARY +extern QFactoryLoader *qt_iconEngineFactoryLoader(); // qicon.cpp +#endif + void QIconLoader::ensureInitialized() { if (!m_initialized) { @@ -116,10 +120,7 @@ void QIconLoader::ensureInitialized() if (m_systemTheme.isEmpty()) m_systemTheme = fallbackTheme(); #ifndef QT_NO_LIBRARY - QFactoryLoader iconFactoryLoader(QIconEngineFactoryInterface_iid, - QLatin1String("/iconengines"), - Qt::CaseInsensitive); - if (iconFactoryLoader.keyMap().key(QLatin1String("svg"), -1) != -1) + if (qt_iconEngineFactoryLoader()->keyMap().key(QLatin1String("svg"), -1) != -1) m_supportsSvg = true; #endif //QT_NO_LIBRARY } -- cgit v1.2.3 From 2cea97bc617784c127bc9599e5315932b47cc8a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Mon, 22 Apr 2013 13:32:25 +0200 Subject: Fixed documentation of QWidget::mouseDoubleClickEvent. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since change 3bb902495291c5 the documentation is invalid. Task-number: QTBUG-29680 Change-Id: I7d5fcb6bc490aa5cba83439d33f798459640c42d Reviewed-by: Jørgen Lind --- src/widgets/kernel/qwidget.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 90cfb3446f..3b796fe35b 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -8434,8 +8434,6 @@ void QWidget::mouseReleaseEvent(QMouseEvent *event) This event handler, for event \a event, can be reimplemented in a subclass to receive mouse double click events for the widget. - The default implementation generates a normal mouse press event. - \note The widget will also receive mouse press and mouse release events in addition to the double click event. It is up to the developer to ensure that the application interprets these events -- cgit v1.2.3 From b4985215df767c14ddd888cbb2919be3a7617cfd Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Mon, 22 Apr 2013 17:28:04 +0200 Subject: QNX host lookup: do not try to load libresolv.so, it is not there Not trying to load the lib saves 30 - 50ms upon an apps' 1st host lookup. Task-number: QTBUG-30809 Change-Id: Id893cec09ff57494776625700c93f7efe96fcc6b Reviewed-by: Thomas McGuire Reviewed-by: Rafael Roquetto --- src/network/kernel/qhostinfo_unix.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/kernel/qhostinfo_unix.cpp b/src/network/kernel/qhostinfo_unix.cpp index fac83b922b..04daf2ecdd 100644 --- a/src/network/kernel/qhostinfo_unix.cpp +++ b/src/network/kernel/qhostinfo_unix.cpp @@ -92,7 +92,7 @@ static res_state_ptr local_res = 0; static void resolveLibrary() { -#ifndef QT_NO_LIBRARY +#if !defined(QT_NO_LIBRARY) && !defined(Q_OS_QNX) QLibrary lib(QLatin1String("resolv")); if (!lib.load()) return; -- cgit v1.2.3 From ded4613ae43842d4b960137843eb83a7472adc65 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 23 Apr 2013 16:46:26 +0200 Subject: Windows: Position full screen windows on the correct screen. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Find effective screen by searching the virtual sibling that contains the center as does QDesktopWidget::screenNumber(). Task-number: QTBUG-30724 Change-Id: I8441ab4f3e5ee8169613a82f150d1a4f1777b662 Reviewed-by: Samuel Rødal --- src/plugins/platforms/windows/qwindowswindow.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 2a5e08cf41..9a9877b43f 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -1366,9 +1366,23 @@ void QWindowsWindow::setWindowState(Qt::WindowState state) } } +// Return the effective screen for full screen mode in a virtual desktop. +static const QScreen *effectiveScreen(const QWindow *w) +{ + QPoint center = w->geometry().center(); + if (!w->isTopLevel()) + center = w->mapToGlobal(center); + const QScreen *screen = w->screen(); + if (!screen->geometry().contains(center)) + foreach (const QScreen *sibling, screen->virtualSiblings()) + if (sibling->geometry().contains(center)) + return sibling; + return screen; +} + bool QWindowsWindow::isFullScreen_sys() const { - return geometry_sys() == window()->screen()->geometry(); + return geometry_sys() == effectiveScreen(window())->geometry(); } /*! @@ -1444,7 +1458,7 @@ void QWindowsWindow::setWindowState_sys(Qt::WindowState newState) newStyle |= WS_VISIBLE; setStyle(newStyle); - const QRect r = window()->screen()->geometry(); + const QRect r = effectiveScreen(window())->geometry(); const UINT swpf = SWP_FRAMECHANGED | SWP_NOACTIVATE; const bool wasSync = testFlag(SynchronousGeometryChangeEvent); setFlag(SynchronousGeometryChangeEvent); -- cgit v1.2.3 From 4afb128d312a7f2a1d94e2becc5aaaec47326869 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 22 Apr 2013 15:52:30 +0200 Subject: iOS: Don't try to set screen orientation before QApplication startup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We create our QIOSViewController in didFinishLaunchingWithOptions, and schedule a timer to run the user's main. If the device is placed in landscape orientation at startup, we will receive a willRotateToInterfaceOrientation message before the timer is triggered to run the user's main, which means we do not yet have a QApplication. To fix this crash we exit early, but we might have to store the new orientation for later, and make sure the initial QScreen is then created with the correct orientation. Change-Id: I0cc02f0d36b992d190736e98858dc7d002d595b7 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/ios/qiosviewcontroller.mm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm index 404b213966..9d3447a2e4 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.mm +++ b/src/plugins/platforms/ios/qiosviewcontroller.mm @@ -78,6 +78,10 @@ - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { Q_UNUSED(duration); + + if (!QCoreApplication::instance()) + return; // FIXME: Store orientation for later (?) + Qt::ScreenOrientation orientation = toQtScreenOrientation(UIDeviceOrientation(toInterfaceOrientation)); if (orientation == -1) return; -- cgit v1.2.3 From 78fc0d4872bc4908d4615c3975d566fa2e1839eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Kundr=C3=A1t?= Date: Tue, 23 Apr 2013 16:03:36 +0200 Subject: Respond to the _NET_WM_CONTEXT_HELP WM_PROTOCOLS message MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This change restores a proper function of the "(?)" button in the window decorations which is used as a clue for the user to check what a particular widget is supposed to do. The change is only implemented for QtWidgets because the underlying QWhatsThis is inherently widget-specific -- which is why it sends an event to QGuiApplication, but only processes it in the QtWidget-specific QApplication. Thanks to Alberto Mardegan and Gunnar Sletta for their feedback on this patch. Change-Id: Ibb912e3960f1e9aec54c5ed77ade1c6744d6ca23 Reviewed-by: Alberto Mardegan Reviewed-by: Gunnar Sletta Reviewed-by: Samuel Rødal --- src/plugins/platforms/xcb/qxcbwindow.cpp | 5 +++++ src/widgets/kernel/qapplication.cpp | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 4090758d36..7d6d6a94b3 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -1492,6 +1492,11 @@ void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *even connection()->setTime(event->data.data32[1]); m_syncValue.lo = event->data.data32[2]; m_syncValue.hi = event->data.data32[3]; +#ifndef QT_NO_WHATSTHIS + } else if (event->data.data32[0] == atom(QXcbAtom::_NET_WM_CONTEXT_HELP)) { + QEvent *e = new QEvent(QEvent::EnterWhatsThisMode); + QGuiApplication::postEvent(QGuiApplication::instance(), e); +#endif } else { qWarning() << "QXcbWindow: Unhandled WM_PROTOCOLS message:" << connection()->atomName(event->data.data32[0]); } diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index d036f6bada..b8d3117a41 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -72,6 +72,9 @@ #include #include #include +#ifndef QT_NO_WHATSTHIS +#include +#endif #include "private/qkeymapper_p.h" @@ -1856,6 +1859,11 @@ bool QApplication::event(QEvent *e) } else if (te->timerId() == d->toolTipFallAsleep.timerId()) { d->toolTipFallAsleep.stop(); } +#ifndef QT_NO_WHATSTHIS + } else if (e->type() == QEvent::EnterWhatsThisMode) { + QWhatsThis::enterWhatsThisMode(); + return true; +#endif } if(e->type() == QEvent::LanguageChange) { -- cgit v1.2.3 From 1c1727504708212c9469bc054103580c016315db Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Wed, 24 Apr 2013 16:18:37 +0200 Subject: Run the CMake tests with QPrinter, not QPrintDialog. QPrinter is not implemented on android, so the test fails to link there. Change-Id: I10ca0179323362a9c9f74325332043c968d67d3c Reviewed-by: Sean Harmer --- tests/auto/cmake/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/cmake/CMakeLists.txt b/tests/auto/cmake/CMakeLists.txt index 04e73cc7c9..25f2ab6a87 100644 --- a/tests/auto/cmake/CMakeLists.txt +++ b/tests/auto/cmake/CMakeLists.txt @@ -106,7 +106,7 @@ if (NOT NO_WIDGETS) list(APPEND qt_module_includes Widgets QWidget OpenGL QGLBuffer - PrintSupport QPrintDialog + PrintSupport QPrinter ) endif() -- cgit v1.2.3 From b43609404cd645faabf88f0677d09c246f8f731c Mon Sep 17 00:00:00 2001 From: hluk Date: Mon, 22 Apr 2013 21:04:25 +0200 Subject: Fix segfault while handling system-wide shortcuts with xcb MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I8485031edc623f99b4b858d4f777be43f4bc3264 Reviewed-by: Samuel Rødal Reviewed-by: Gunnar Sletta --- src/plugins/platforms/xcb/qxcbconnection.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index cb80fdfbd3..de3d487c4b 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -422,7 +422,7 @@ break; if (QXcbWindow *platformWindow = platformWindowFromId(e->event)) { \ handled = QWindowSystemInterface::handleNativeEvent(platformWindow->window(), m_nativeInterface->genericEventFilterType(), event, &result); \ if (!handled) \ - m_keyboard->handler(m_focusWindow, e); \ + m_keyboard->handler(m_focusWindow ? m_focusWindow : platformWindow, e); \ } \ } \ break; -- cgit v1.2.3 From 5c6e2882ddcc6580192507dbe8d0769b1b4c1bc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Mon, 8 Apr 2013 08:32:43 +0200 Subject: Improved robustness of threaded rendering in hellowindow example. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously resizes along with the animation was implemented using queued signals and slots, potentially causing a huge lag between the size of the window and the rendered contents. Now the animation is always driven by the rendering thread and is triggered based on the window's isExposed() status. Change-Id: Ifd89a63c2a436671a7b15326ff56be9ec2a5362d Reviewed-by: Jørgen Lind Reviewed-by: Gunnar Sletta --- examples/opengl/hellowindow/hellowindow.cpp | 56 +++++++++++++++++++++-------- examples/opengl/hellowindow/hellowindow.h | 25 +++++++------ 2 files changed, 55 insertions(+), 26 deletions(-) diff --git a/examples/opengl/hellowindow/hellowindow.cpp b/examples/opengl/hellowindow/hellowindow.cpp index bcb28e9d96..b5ffbd63a2 100644 --- a/examples/opengl/hellowindow/hellowindow.cpp +++ b/examples/opengl/hellowindow/hellowindow.cpp @@ -46,6 +46,7 @@ Renderer::Renderer(const QSurfaceFormat &format, Renderer *share, QScreen *screen) : m_initialized(false) , m_format(format) + , m_currentWindow(0) { m_context = new QOpenGLContext(this); if (screen) @@ -57,7 +58,7 @@ Renderer::Renderer(const QSurfaceFormat &format, Renderer *share, QScreen *scree } HelloWindow::HelloWindow(const QSharedPointer &renderer) - : m_colorIndex(0), m_renderer(renderer), m_timer(0) + : m_colorIndex(0), m_renderer(renderer) { setSurfaceType(QWindow::OpenGLSurface); setFlags(Qt::Window | Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint); @@ -68,21 +69,12 @@ HelloWindow::HelloWindow(const QSharedPointer &renderer) create(); - connect(this, SIGNAL(needRender(QSurface *, const QColor &, const QSize &)), - renderer.data(), SLOT(render(QSurface *, const QColor &, const QSize &))); - updateColor(); } void HelloWindow::exposeEvent(QExposeEvent *) { - render(); - - if (!m_timer) { - m_timer = new QTimer(this); - connect(m_timer, SIGNAL(timeout()), this, SLOT(render())); - m_timer->start(10); - } + m_renderer->setAnimating(this, isExposed()); } void HelloWindow::mousePressEvent(QMouseEvent *) @@ -90,14 +82,16 @@ void HelloWindow::mousePressEvent(QMouseEvent *) updateColor(); } -void HelloWindow::render() +QColor HelloWindow::color() const { - if (isExposed()) - emit needRender(this, m_color, size()); + QMutexLocker locker(&m_colorLock); + return m_color; } void HelloWindow::updateColor() { + QMutexLocker locker(&m_colorLock); + QColor colors[] = { QColor(100, 255, 0), @@ -108,11 +102,41 @@ void HelloWindow::updateColor() m_colorIndex = 1 - m_colorIndex; } -void Renderer::render(QSurface *surface, const QColor &color, const QSize &viewSize) +void Renderer::setAnimating(HelloWindow *window, bool animating) +{ + QMutexLocker locker(&m_windowLock); + if (m_windows.contains(window) == animating) + return; + + if (animating) { + m_windows << window; + if (m_windows.size() == 1) + QTimer::singleShot(0, this, SLOT(render())); + } else { + m_currentWindow = 0; + m_windows.removeOne(window); + } +} + +void Renderer::render() { + QMutexLocker locker(&m_windowLock); + + if (m_windows.isEmpty()) + return; + + HelloWindow *surface = m_windows.at(m_currentWindow); + QColor color = surface->color(); + + m_currentWindow = (m_currentWindow + 1) % m_windows.size(); + if (!m_context->makeCurrent(surface)) return; + QSize viewSize = surface->size(); + + locker.unlock(); + if (!m_initialized) { initialize(); m_initialized = true; @@ -146,6 +170,8 @@ void Renderer::render(QSurface *surface, const QColor &color, const QSize &viewS m_context->swapBuffers(surface); m_fAngle += 1.0f; + + QTimer::singleShot(0, this, SLOT(render())); } void Renderer::paintQtLogo() diff --git a/examples/opengl/hellowindow/hellowindow.h b/examples/opengl/hellowindow/hellowindow.h index 3d6ac80cfe..6d66f0204a 100644 --- a/examples/opengl/hellowindow/hellowindow.h +++ b/examples/opengl/hellowindow/hellowindow.h @@ -41,10 +41,13 @@ #include #include +#include #include #include #include +class HelloWindow; + class Renderer : public QObject { Q_OBJECT @@ -54,8 +57,10 @@ public: QSurfaceFormat format() const { return m_format; } -public slots: - void render(QSurface *surface, const QColor &color, const QSize &viewSize); + void setAnimating(HelloWindow *window, bool animating); + +private slots: + void render(); private: void initialize(); @@ -78,30 +83,28 @@ private: QSurfaceFormat m_format; QOpenGLContext *m_context; QOpenGLShaderProgram *m_program; + + QList m_windows; + int m_currentWindow; + + QMutex m_windowLock; }; class HelloWindow : public QWindow { - Q_OBJECT - public: explicit HelloWindow(const QSharedPointer &renderer); + QColor color() const; void updateColor(); void exposeEvent(QExposeEvent *event); -signals: - void needRender(QSurface *surface, const QColor &color, const QSize &viewSize); - -private slots: - void render(); - private: void mousePressEvent(QMouseEvent *); int m_colorIndex; QColor m_color; const QSharedPointer m_renderer; - QTimer *m_timer; + mutable QMutex m_colorLock; }; -- cgit v1.2.3 From 2e0575ce89809ad782440b7b868fbf2a8ad6852a Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Wed, 17 Apr 2013 14:54:21 +0200 Subject: Fix windows expose logic Make sure the value of QWindowsWindow::isExposed is in sync with regions we expose. This provoked a couple of existing issues in the qwidget test. setWindowGeometry tested that windows with invalid sizes got exposed on screen. They didn't, but because the plugin sent bogus events, these used to pass. Same with windowMoveResize. The expect fails are also rather bogus. Showing invalid-size widgets could be considered undefined behavior. The Window manager could resize it, choose to not show it at all, etc, but they now pass on windows. resizeEvent has been broken since 5.0.0, but the test didn't spin the event loop so the second event didn't get delivered before the test completed. Task-number: QTBUG-30744 Change-Id: I3a9efcd095f366126a87739f4248185b6c81d407 Reviewed-by: Friedemann Kleint --- src/plugins/platforms/windows/qwindowscontext.cpp | 3 -- src/plugins/platforms/windows/qwindowswindow.cpp | 59 ++++++++++++----------- src/plugins/platforms/windows/qwindowswindow.h | 7 +-- tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp | 30 +++++++----- 4 files changed, 54 insertions(+), 45 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 3f4555a31f..872fd07729 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -842,9 +842,6 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, case QtWindows::FocusOutEvent: handleFocusEvent(et, platformWindow); return true; - case QtWindows::ShowEvent: - platformWindow->handleShown(); - return false; // Indicate transient children should be shown by windows (SW_PARENTOPENING) case QtWindows::HideEvent: platformWindow->handleHidden(); return false;// Indicate transient children should be hidden by windows (SW_PARENTCLOSING) diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 9a9877b43f..1ff98a3d29 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -839,6 +839,15 @@ QWindowsWindow::~QWindowsWindow() destroyIcon(); } +void QWindowsWindow::fireExpose(const QRegion ®ion, bool force) +{ + if (region.isEmpty() && !force) + clearFlag(Exposed); + else + setFlag(Exposed); + QWindowSystemInterface::handleExposeEvent(window(), region); +} + void QWindowsWindow::destroyWindow() { if (QWindowsContext::verboseIntegration || QWindowsContext::verboseWindows) @@ -942,13 +951,19 @@ void QWindowsWindow::setVisible(bool visible) if (m_data.hwnd) { if (visible) { show_sys(); - QWindowSystemInterface::handleExposeEvent(window(), - QRect(QPoint(), geometry().size())); + + // 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))) + fireExpose(QRect(0, 0, w->width(), w->height())); + } else { if (hasMouseCapture()) setMouseGrabEnabled(false); hide_sys(); - QWindowSystemInterface::handleExposeEvent(window(), QRegion()); + fireExpose(QRegion()); } } } @@ -1094,14 +1109,9 @@ void QWindowsWindow::setParent_sys(const QPlatformWindow *parent) const } } -void QWindowsWindow::handleShown() -{ - QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), geometry().size())); -} - void QWindowsWindow::handleHidden() { - QWindowSystemInterface::handleExposeEvent(window(), QRegion()); + fireExpose(QRegion()); } void QWindowsWindow::setGeometry(const QRect &rectIn) @@ -1267,28 +1277,21 @@ bool QWindowsWindow::handleWmPaint(HWND hwnd, UINT message, if (message == WM_ERASEBKGND) // Backing store - ignored. return true; PAINTSTRUCT ps; - if (testFlag(OpenGLSurface)) { - // Observed painting problems with Aero style disabled (QTBUG-7865). - if (testFlag(OpenGLDoubleBuffered)) - InvalidateRect(hwnd, 0, false); - BeginPaint(hwnd, &ps); - QWindowSystemInterface::handleExposeEvent(window(), QRegion(qrectFromRECT(ps.rcPaint))); - if (!QWindowsContext::instance()->asyncExpose()) - QWindowSystemInterface::flushWindowSystemEvents(); - EndPaint(hwnd, &ps); - } else { - BeginPaint(hwnd, &ps); - const QRect updateRect = qrectFromRECT(ps.rcPaint); + // Observed painting problems with Aero style disabled (QTBUG-7865). + if (testFlag(OpenGLSurface) && testFlag(OpenGLDoubleBuffered)) + InvalidateRect(hwnd, 0, false); - if (QWindowsContext::verboseIntegration) - qDebug() << __FUNCTION__ << this << window() << updateRect; + BeginPaint(hwnd, &ps); - QWindowSystemInterface::handleExposeEvent(window(), QRegion(updateRect)); - if (!QWindowsContext::instance()->asyncExpose()) - QWindowSystemInterface::flushWindowSystemEvents(); - EndPaint(hwnd, &ps); - } + // If the a window is obscured by another window (such as a child window) + // we still need to send isExposed=true, for compatibility. + // Our tests depend on it. + fireExpose(QRegion(qrectFromRECT(ps.rcPaint)), true); + if (!QWindowsContext::instance()->asyncExpose()) + QWindowSystemInterface::flushWindowSystemEvents(); + + EndPaint(hwnd, &ps); return true; } diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h index 2117ca50b8..fed9d089df 100644 --- a/src/plugins/platforms/windows/qwindowswindow.h +++ b/src/plugins/platforms/windows/qwindowswindow.h @@ -133,7 +133,8 @@ public: WithinSetStyle = 0x800, WithinDestroy = 0x1000, TouchRegistered = 0x2000, - AlertState = 0x4000 + AlertState = 0x4000, + Exposed = 0x08000 }; struct WindowData @@ -161,7 +162,7 @@ public: virtual void setVisible(bool visible); bool isVisible() const; - virtual bool isExposed() const { return m_windowState != Qt::WindowMinimized && isVisible(); } + virtual bool isExposed() const { return testFlag(Exposed); } virtual bool isActive() const; virtual bool isEmbedded(const QPlatformWindow *parentWindow) const; virtual QPoint mapToGlobal(const QPoint &pos) const; @@ -217,7 +218,6 @@ public: void handleMoved(); void handleResized(int wParam); - void handleShown(); void handleHidden(); static inline HWND handleOf(const QWindow *w); @@ -278,6 +278,7 @@ private: void handleGeometryChange(); void handleWindowStateChange(Qt::WindowState state); inline void destroyIcon(); + void fireExpose(const QRegion ®ion, bool force=false); mutable WindowData m_data; mutable unsigned m_flags; diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index 69d890fb7a..25e1dc3fa0 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -2089,11 +2089,14 @@ public: void tst_QWidget::resizeEvent() { + QSKIP("QTBUG-30744"); + { QWidget wParent; wParent.resize(200, 200); ResizeWidget wChild(&wParent); wParent.show(); + QTest::qWaitForWindowExposed(&wParent); QCOMPARE (wChild.m_resizeEventCount, 1); // initial resize event before paint wParent.hide(); QSize safeSize(640,480); @@ -2109,6 +2112,7 @@ void tst_QWidget::resizeEvent() ResizeWidget wTopLevel; wTopLevel.resize(200, 200); wTopLevel.show(); + QTest::qWaitForWindowExposed(&wTopLevel); QCOMPARE (wTopLevel.m_resizeEventCount, 1); // initial resize event before paint for toplevels wTopLevel.hide(); QSize safeSize(640,480); @@ -2117,6 +2121,7 @@ void tst_QWidget::resizeEvent() wTopLevel.resize(safeSize); QCOMPARE (wTopLevel.m_resizeEventCount, 1); wTopLevel.show(); + QTest::qWaitForWindowExposed(&wTopLevel); QCOMPARE (wTopLevel.m_resizeEventCount, 2); } } @@ -4428,11 +4433,8 @@ void tst_QWidget::setWindowGeometry() widget.setGeometry(rect); widget.show(); - QVERIFY(QTest::qWaitForWindowExposed(&widget)); - if (m_platform == QStringLiteral("windows")) { - QEXPECT_FAIL("130,100 0x200, flags 0", "QTBUG-26424", Continue); - QEXPECT_FAIL("130,50 0x0, flags 0", "QTBUG-26424", Continue); - } + if (rect.isValid()) + QVERIFY(QTest::qWaitForWindowExposed(&widget)); QTRY_COMPARE(widget.geometry(), rect); // setGeometry() while shown @@ -4462,7 +4464,8 @@ void tst_QWidget::setWindowGeometry() // show() again, geometry() should still be the same widget.show(); - QVERIFY(QTest::qWaitForWindowExposed(&widget)); + if (rect.isValid()) + QVERIFY(QTest::qWaitForWindowExposed(&widget)); QTRY_COMPARE(widget.geometry(), rect); // final hide(), again geometry() should be unchanged @@ -4478,7 +4481,8 @@ void tst_QWidget::setWindowGeometry() widget.setWindowFlags(Qt::WindowFlags(windowFlags)); widget.show(); - QVERIFY(QTest::qWaitForWindowExposed(&widget)); + if (rect.isValid()) + QVERIFY(QTest::qWaitForWindowExposed(&widget)); widget.setGeometry(rect); QTest::qWait(10); QTRY_COMPARE(widget.geometry(), rect); @@ -4510,7 +4514,8 @@ void tst_QWidget::setWindowGeometry() // show() again, geometry() should still be the same widget.show(); - QVERIFY(QTest::qWaitForWindowExposed(&widget)); + if (rect.isValid()) + QVERIFY(QTest::qWaitForWindowExposed(&widget)); QTest::qWait(10); QTRY_COMPARE(widget.geometry(), rect); @@ -4655,7 +4660,8 @@ void tst_QWidget::windowMoveResize() // show() again, pos() should be the same widget.show(); - QVERIFY(QTest::qWaitForWindowExposed(&widget)); + if (rect.isValid()) + QVERIFY(QTest::qWaitForWindowExposed(&widget)); QApplication::processEvents(); QTRY_COMPARE(widget.pos(), rect.topLeft()); QTRY_COMPARE(widget.size(), rect.size()); @@ -4674,7 +4680,8 @@ void tst_QWidget::windowMoveResize() widget.setWindowFlags(Qt::WindowFlags(windowFlags)); widget.show(); - QVERIFY(QTest::qWaitForWindowExposed(&widget)); + if (rect.isValid()) + QVERIFY(QTest::qWaitForWindowExposed(&widget)); QApplication::processEvents(); widget.move(rect.topLeft()); widget.resize(rect.size()); @@ -4724,7 +4731,8 @@ void tst_QWidget::windowMoveResize() // show() again, pos() should be the same widget.show(); - QVERIFY(QTest::qWaitForWindowExposed(&widget)); + if (rect.isValid()) + QVERIFY(QTest::qWaitForWindowExposed(&widget)); QTest::qWait(10); QTRY_COMPARE(widget.pos(), rect.topLeft()); QTRY_COMPARE(widget.size(), rect.size()); -- cgit v1.2.3 From b9db3e4785d965905549d2033e0707922c8b74b5 Mon Sep 17 00:00:00 2001 From: Jan Arve Saether Date: Thu, 25 Apr 2013 15:11:47 +0200 Subject: Do not include the treeview header if its hidden Previously, accessibleTree->child(0) would return an interface for the header even if it was hidden. Also, the assertion was wrong since the index would be 0 if both row and column were 0. The assertion was actually found while using the project explorer of Qt Creator (2.7) Change-Id: I9f3cc2c13b6887569d10c4e062a64552f898231a Reviewed-by: Frederik Gladhorn --- src/plugins/accessible/widgets/itemviews.cpp | 3 ++- tests/auto/other/qaccessibility/tst_qaccessibility.cpp | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/plugins/accessible/widgets/itemviews.cpp b/src/plugins/accessible/widgets/itemviews.cpp index 4ddd39f7ea..d460ec2c98 100644 --- a/src/plugins/accessible/widgets/itemviews.cpp +++ b/src/plugins/accessible/widgets/itemviews.cpp @@ -120,6 +120,8 @@ QHeaderView *QAccessibleTable::horizontalHeader() const #ifndef QT_NO_TREEVIEW } else if (const QTreeView *tv = qobject_cast(view())) { header = tv->header(); + if (header && header->isHidden()) + header = 0; #endif } return header; @@ -766,7 +768,6 @@ int QAccessibleTree::indexOfChild(const QAccessibleInterface *iface) const int column = cell->m_index.column(); int index = row * view()->model()->columnCount() + column; - Q_ASSERT(index >= treeView->model()->columnCount()); return index; } else if (iface->role() == QAccessible::ColumnHeader){ const QAccessibleTableHeaderCell* cell = static_cast(iface); diff --git a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp index af8e4472ed..557189f4e2 100644 --- a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp +++ b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp @@ -2600,6 +2600,12 @@ void tst_QAccessibility::treeTest() QCOMPARE(iface->indexOfChild(child2), 4); QCOMPARE(child2->text(QAccessible::Name), QString("Austria")); + treeView->setHeaderHidden(true); + QAccessibleInterface *accSpain = iface->child(0); + QCOMPARE(accSpain->role(), QAccessible::TreeItem); + QCOMPARE(iface->indexOfChild(accSpain), 0); + treeView->setHeaderHidden(false); + QTestAccessibility::clearEvents(); // table 2 -- cgit v1.2.3 From 42760e43eaa64e834809ef5fb01a83cfb75f4f04 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 23 Apr 2013 16:08:41 +0200 Subject: Windows native save file dialog: Do not append suffix afterwards. Instead, set the currently selected filter's suffix as default suffix of the dialog unless another default suffix has been set. This emulates the behavior of Qt 4 behavior which would set the selected name filter's suffix as default suffix in QFileDialog::getSaveFileName(). Task-number: QTBUG-30748 Change-Id: I111cd6190ddab8775a0fa72b94b3c728dd411c5e Reviewed-by: Oliver Wolff Reviewed-by: Andy Shaw --- .../platforms/windows/qwindowsdialoghelpers.cpp | 54 ++++++++++++++++------ 1 file changed, 39 insertions(+), 15 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp index 5b84725edf..33b4eb4771 100644 --- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp +++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp @@ -833,6 +833,7 @@ public: bool hideFiltersDetails() const { return m_hideFiltersDetails; } void setHideFiltersDetails(bool h) { m_hideFiltersDetails = h; } void setDefaultSuffix(const QString &s); + inline bool hasDefaultSuffix() const { return m_hasDefaultSuffix; } inline void setLabelText(QFileDialogOptions::DialogLabel l, const QString &text); // Return the selected files for tracking in OnSelectionChanged(). @@ -857,6 +858,7 @@ public slots: protected: explicit QWindowsNativeFileDialogBase(const QWindowsFileDialogSharedData &data); bool init(const CLSID &clsId, const IID &iid); + void setDefaultSuffixSys(const QString &s); inline IFileDialog * fileDialog() const { return m_fileDialog; } static QString itemPath(IShellItem *item); static QStringList libraryItemFolders(IShellItem *item); @@ -873,12 +875,13 @@ private: DWORD m_cookie; QStringList m_nameFilters; bool m_hideFiltersDetails; + bool m_hasDefaultSuffix; QWindowsFileDialogSharedData m_data; }; QWindowsNativeFileDialogBase::QWindowsNativeFileDialogBase(const QWindowsFileDialogSharedData &data) : m_fileDialog(0), m_dialogEvents(0), m_cookie(0), m_hideFiltersDetails(false), - m_data(data) + m_hasDefaultSuffix(false), m_data(data) { } @@ -1188,6 +1191,15 @@ void QWindowsNativeFileDialogBase::setNameFilters(const QStringList &filters) void QWindowsNativeFileDialogBase::setDefaultSuffix(const QString &s) { + setDefaultSuffixSys(s); + m_hasDefaultSuffix = !s.isEmpty(); +} + +void QWindowsNativeFileDialogBase::setDefaultSuffixSys(const QString &s) +{ + // If this parameter is non-empty, it will be appended by the dialog for the 'Any files' + // filter ('*'). If this parameter is non-empty and the current filter has a suffix, + // the dialog will append the filter's suffix. wchar_t *wSuffix = const_cast(reinterpret_cast(s.utf16())); m_fileDialog->SetDefaultExtension(wSuffix); } @@ -1321,33 +1333,45 @@ HRESULT QWindowsNativeFileDialogEventHandler::OnFileOk(IFileDialog *) class QWindowsNativeSaveFileDialog : public QWindowsNativeFileDialogBase { + Q_OBJECT public: - explicit QWindowsNativeSaveFileDialog(const QWindowsFileDialogSharedData &data) : - QWindowsNativeFileDialogBase(data) {} + explicit QWindowsNativeSaveFileDialog(const QWindowsFileDialogSharedData &data); virtual QStringList selectedFiles() const; virtual QStringList dialogResult() const; + +private slots: + void slotFilterSelected(const QString &); }; -// Append a suffix from the name filter "Foo files (*.foo;*.bar)" -// unless the file name already has one. -static inline QString appendSuffix(const QString &fileName, const QString &filter) +// Return the first suffix from the name filter "Foo files (*.foo;*.bar)" -> "foo". +static inline QString suffixFromFilter(const QString &filter) { - const int lastDot = fileName.lastIndexOf(QLatin1Char('.')); - const int lastSlash = fileName.lastIndexOf(QLatin1Char('/')); - if (lastDot >= 0 && (lastSlash == -1 || lastDot > lastSlash)) - return fileName; int suffixPos = filter.indexOf(QLatin1String("(*.")); if (suffixPos < 0) - return fileName; + return QString(); suffixPos += 3; int endPos = filter.indexOf(QLatin1Char(' '), suffixPos + 1); if (endPos < 0) endPos = filter.indexOf(QLatin1Char(';'), suffixPos + 1); if (endPos < 0) endPos = filter.indexOf(QLatin1Char(')'), suffixPos + 1); - if (endPos < 0) - return fileName; - return fileName + QLatin1Char('.') + filter.mid(suffixPos, endPos - suffixPos); + return endPos >= 0 ? filter.mid(suffixPos, endPos - suffixPos) : QString(); +} + +QWindowsNativeSaveFileDialog::QWindowsNativeSaveFileDialog(const QWindowsFileDialogSharedData &data) + : QWindowsNativeFileDialogBase(data) +{ + connect(this, &QWindowsNativeFileDialogBase::filterSelected, + this, &QWindowsNativeSaveFileDialog::slotFilterSelected); +} + +void QWindowsNativeSaveFileDialog::slotFilterSelected(const QString &filter) +{ + // Cause the dialog to append the suffix of the current filter unless a default + // suffix is set (Note: Qt 4.8 sets the selected filter's suffix before + // calling GetSaveFileName()). + if (!hasDefaultSuffix()) + setDefaultSuffixSys(suffixFromFilter(filter)); } QStringList QWindowsNativeSaveFileDialog::dialogResult() const @@ -1355,7 +1379,7 @@ QStringList QWindowsNativeSaveFileDialog::dialogResult() const QStringList result; IShellItem *item = 0; if (SUCCEEDED(fileDialog()->GetResult(&item)) && item) - result.push_back(appendSuffix(QWindowsNativeFileDialogBase::itemPath(item), selectedNameFilter())); + result.push_back(QWindowsNativeFileDialogBase::itemPath(item)); return result; } -- cgit v1.2.3 From 0dea24054f15f156fdc8b8d2d32408d8371f4e13 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 19 Apr 2013 16:00:29 +0200 Subject: fix QProcessEnvironment documentation re case conversion Change-Id: I854382d1d431ee084ef0faa2e240e093b9183ec8 Reviewed-by: Daniel Teske Reviewed-by: Jerome Pasion --- src/corelib/io/qprocess.cpp | 37 +++++++++++-------------------------- 1 file changed, 11 insertions(+), 26 deletions(-) diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index 3993cf5002..59b6db7c79 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -125,16 +125,15 @@ QT_BEGIN_NAMESPACE The environment of the calling process can be obtained using QProcessEnvironment::systemEnvironment(). - On Unix systems, the variable names are case-sensitive. For that reason, - this class will not touch the names of the variables. Note as well that + On Unix systems, the variable names are case-sensitive. Note that the Unix environment allows both variable names and contents to contain arbitrary - binary data (except for the NUL character), but this is not supported by - QProcessEnvironment. This class only supports names and values that are - encodable by the current locale settings (see QTextCodec::codecForLocale). + binary data (except for the NUL character). QProcessEnvironment will preserve + such variables, but does not support manipulating variables whose names or + values are not encodable by the current locale settings (see + QTextCodec::codecForLocale). - On Windows, the variable names are case-insensitive. Therefore, - QProcessEnvironment will always uppercase the names and do case-insensitive - comparisons. + On Windows, the variable names are case-insensitive, but case-preserving. + QProcessEnvironment behaves accordingly. On Windows CE, the concept of environment does not exist. This class will keep the values set for compatibility with other platforms, but the values @@ -298,9 +297,6 @@ void QProcessEnvironment::clear() Returns true if the environment variable of name \a name is found in this QProcessEnvironment object. - On Windows, variable names are case-insensitive, so the key is converted - to uppercase before searching. On other systems, names are case-sensitive - so no trasformation is applied. \sa insert(), value() */ @@ -314,10 +310,6 @@ bool QProcessEnvironment::contains(const QString &name) const into this QProcessEnvironment object. If that variable already existed, it is replaced by the new value. - On Windows, variable names are case-insensitive, so this function always - uppercases the variable name before inserting. On other systems, names - are case-sensitive, so no transformation is applied. - On most systems, inserting a variable with no contents will have the same effect for applications as if the variable had not been set at all. However, to guarantee that there are no incompatibilities, to remove a @@ -336,9 +328,6 @@ void QProcessEnvironment::insert(const QString &name, const QString &value) QProcessEnvironment object. If that variable did not exist before, nothing happens. - On Windows, variable names are case-insensitive, so the key is converted - to uppercase before searching. On other systems, names are case-sensitive - so no trasformation is applied. \sa contains(), insert(), value() */ @@ -353,10 +342,6 @@ void QProcessEnvironment::remove(const QString &name) \a name and returns its value. If the variable is not found in this object, then \a defaultValue is returned instead. - On Windows, variable names are case-insensitive, so the key is converted - to uppercase before searching. On other systems, names are case-sensitive - so no trasformation is applied. - \sa contains(), insert(), remove() */ QString QProcessEnvironment::value(const QString &name, const QString &defaultValue) const @@ -376,10 +361,10 @@ QString QProcessEnvironment::value(const QString &name, const QString &defaultVa each environment variable that is set. The environment variable's name and its value are separated by an equal character ('='). - The QStringList contents returned by this function are suitable for use - with the QProcess::setEnvironment function. However, it is recommended - to use QProcess::setProcessEnvironment instead since that will avoid - unnecessary copying of the data. + The QStringList contents returned by this function are suitable for + presentation. + Use with the QProcess::setEnvironment function is not recommended due to + potential encoding problems under Unix, and worse performance. \sa systemEnvironment(), QProcess::systemEnvironment(), QProcess::environment(), QProcess::setEnvironment() -- cgit v1.2.3 From da55d48ad731ee2499467b3e93e11eb3b53df89d Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 19 Apr 2013 18:11:12 +0200 Subject: fix namespaced build Change-Id: I9d0a3cb08de5e91807da7f0358c83b6693ebd1ea Reviewed-by: hjk --- src/corelib/thread/qorderedmutexlocker_p.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/thread/qorderedmutexlocker_p.h b/src/corelib/thread/qorderedmutexlocker_p.h index ec9c6fd91b..0492886cfd 100644 --- a/src/corelib/thread/qorderedmutexlocker_p.h +++ b/src/corelib/thread/qorderedmutexlocker_p.h @@ -53,10 +53,10 @@ // We mean it. // -QT_BEGIN_NAMESPACE - #include +QT_BEGIN_NAMESPACE + /* Locks 2 mutexes in a defined order, avoiding a recursive lock if we're trying to lock the same mutex twice. -- cgit v1.2.3 From 7a1cdac05264204d01f729bb2e1201e08bb9fe3e Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Wed, 24 Apr 2013 13:52:05 +0200 Subject: Cocoa: Remove dead code in QCocoaMenu* MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I56136594f073295ced645d06f657187a54e84384 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoamenu.h | 2 -- src/plugins/platforms/cocoa/qcocoamenu.mm | 5 ----- src/plugins/platforms/cocoa/qcocoamenuitem.mm | 17 ++--------------- 3 files changed, 2 insertions(+), 22 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoamenu.h b/src/plugins/platforms/cocoa/qcocoamenu.h index 439b7f1a75..65f31a33c2 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.h +++ b/src/plugins/platforms/cocoa/qcocoamenu.h @@ -81,8 +81,6 @@ public: void setMinimumWidth(int width); void setFont(const QFont &font); - void setParentItem(QCocoaMenuItem* item); - inline NSMenu *nsMenu() const { return m_nativeMenu; } inline NSMenuItem *nsMenuItem() const diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm index bde9ded14f..2b4c2eaaab 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.mm +++ b/src/plugins/platforms/cocoa/qcocoamenu.mm @@ -289,11 +289,6 @@ void QCocoaMenu::syncSeparatorsCollapsible(bool enable) } } -void QCocoaMenu::setParentItem(QCocoaMenuItem *item) -{ - Q_UNUSED(item); -} - void QCocoaMenu::setEnabled(bool enabled) { m_enabled = enabled; diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm index 2a17ea3dec..d6f0d06be7 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm +++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm @@ -128,7 +128,6 @@ void QCocoaMenuItem::setMenu(QPlatformMenu *menu) QCocoaAutoReleasePool pool; m_menu = static_cast(menu); if (m_menu) { - m_menu->setParentItem(this); } else { // we previously had a menu, but no longer // clear out our item so the nexy sync() call builds a new one @@ -254,23 +253,11 @@ NSMenuItem *QCocoaMenuItem::sync() [m_native setTag:reinterpret_cast(this)]; } -// [m_native setHidden:YES]; -// [m_native setHidden:NO]; [m_native setHidden: !m_isVisible]; [m_native setEnabled: m_enabled]; - QString text = m_text; - QKeySequence accel = m_shortcut; - - { - int st = text.lastIndexOf(QLatin1Char('\t')); - if (st != -1) { - accel = QKeySequence(text.right(text.length()-(st+1))); - text.remove(st, text.length()-st); - } - } - text = mergeText(); - accel = mergeAccel(); + QString text = mergeText(); + QKeySequence accel = mergeAccel(); // Show multiple key sequences as part of the menu text. if (accel.count() > 1) -- cgit v1.2.3 From 370e89f06465a4d61c7b72291115cd7b5a0d576a Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Wed, 24 Apr 2013 13:55:00 +0200 Subject: Cocoa: Reflect menu hierarchy in QCocoaMenu* objects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QCocoaMenu is child of either a QCocoaMenuBar, a QCocoaMenuItem as a submenu, or nothing as a standalone menu. QCocoaMenuItem is child of its containing QCocoaMenu. The parent is set during insertion and cleared during removal. QMenu needs to be updated to avoid double deletion and leaking its own platform menu. Change-Id: Iadf60d8062d7466fa616f84f3761fe322fc9aa2e Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoamenu.mm | 5 +++++ src/plugins/platforms/cocoa/qcocoamenubar.mm | 3 +++ src/plugins/platforms/cocoa/qcocoamenuitem.mm | 3 +++ src/widgets/widgets/qmenu.cpp | 8 ++++---- src/widgets/widgets/qmenu_p.h | 5 +++-- 5 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm index 2b4c2eaaab..df338a1109 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.mm +++ b/src/plugins/platforms/cocoa/qcocoamenu.mm @@ -154,6 +154,7 @@ void QCocoaMenu::insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem * QCocoaMenuItem *cocoaItem = static_cast(menuItem); QCocoaMenuItem *beforeItem = static_cast(before); + menuItem->setParent(this); cocoaItem->sync(); if (beforeItem) { int index = m_menuItems.indexOf(beforeItem); @@ -209,6 +210,10 @@ void QCocoaMenu::removeMenuItem(QPlatformMenuItem *menuItem) qWarning() << Q_FUNC_INFO << "Menu does not contain the item to be removed"; return; } + + if (menuItem->parent() == this) + menuItem->setParent(0); + m_menuItems.removeOne(cocoaItem); if (!cocoaItem->isMerged()) { if (m_nativeMenu != [cocoaItem->nsItem() menu]) { diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.mm b/src/plugins/platforms/cocoa/qcocoamenubar.mm index b880db16a2..b0a53244f4 100644 --- a/src/plugins/platforms/cocoa/qcocoamenubar.mm +++ b/src/plugins/platforms/cocoa/qcocoamenubar.mm @@ -109,6 +109,7 @@ void QCocoaMenuBar::insertMenu(QPlatformMenu *platformMenu, QPlatformMenu *befor [m_nativeMenu addItem: menu->nsMenuItem()]; } + platformMenu->setParent(this); [m_nativeMenu setSubmenu: menu->nsMenu() forItem: menu->nsMenuItem()]; } @@ -123,6 +124,8 @@ void QCocoaMenuBar::removeMenu(QPlatformMenu *platformMenu) } m_menus.removeOne(menu); + if (platformMenu->parent() == this) + platformMenu->setParent(0); NSUInteger realIndex = [m_nativeMenu indexOfItem:menu->nsMenuItem()]; [m_nativeMenu removeItemAtIndex: realIndex]; } diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm index d6f0d06be7..51d9a83345 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm +++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm @@ -124,10 +124,13 @@ void QCocoaMenuItem::setMenu(QPlatformMenu *menu) { if (menu == m_menu) return; + if (m_menu && m_menu->parent() == this) + m_menu->setParent(0); QCocoaAutoReleasePool pool; m_menu = static_cast(menu); if (m_menu) { + m_menu->setParent(this); } else { // we previously had a menu, but no longer // clear out our item so the nexy sync() call builds a new one diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index aaedd7ffee..fde46c9729 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -154,7 +154,7 @@ void QMenuPrivate::init() } platformMenu = QGuiApplicationPrivate::platformTheme()->createPlatformMenu(); - if (platformMenu) { + if (!platformMenu.isNull()) { QObject::connect(platformMenu, SIGNAL(aboutToShow()), q, SIGNAL(aboutToShow())); QObject::connect(platformMenu, SIGNAL(aboutToHide()), q, SIGNAL(aboutToHide())); } @@ -2411,7 +2411,7 @@ void QMenu::changeEvent(QEvent *e) if (d->tornPopup) // torn-off menu d->tornPopup->setEnabled(isEnabled()); d->menuAction->setEnabled(isEnabled()); - if (d->platformMenu) + if (!d->platformMenu.isNull()) d->platformMenu->setEnabled(isEnabled()); } QWidget::changeEvent(e); @@ -2992,7 +2992,7 @@ void QMenu::actionEvent(QActionEvent *e) d->widgetItems.remove(e->action()); } - if (d->platformMenu) { + if (!d->platformMenu.isNull()) { if (e->type() == QEvent::ActionAdded) { QPlatformMenuItem *menuItem = QGuiApplicationPrivate::platformTheme()->createPlatformMenuItem(); @@ -3201,7 +3201,7 @@ void QMenu::setSeparatorsCollapsible(bool collapse) d->updateActionRects(); update(); } - if (d->platformMenu) + if (!d->platformMenu.isNull()) d->platformMenu->syncSeparatorsCollapsible(collapse); } diff --git a/src/widgets/widgets/qmenu_p.h b/src/widgets/widgets/qmenu_p.h index 6cc88c56e2..15f3c92127 100644 --- a/src/widgets/widgets/qmenu_p.h +++ b/src/widgets/widgets/qmenu_p.h @@ -101,7 +101,8 @@ public: ~QMenuPrivate() { delete scroll; - delete platformMenu; + if (!platformMenu.isNull() && !platformMenu->parent()) + delete platformMenu.data(); #if defined(Q_OS_WINCE) && !defined(QT_NO_MENUBAR) delete wce_menu; #endif @@ -228,7 +229,7 @@ public: //menu fading/scrolling effects bool doChildEffects; - QPlatformMenu *platformMenu; + QPointer platformMenu; QPointer actionAboutToTrigger; -- cgit v1.2.3 From 220b2b92b62fb6c45a31e2a8f80e26f115166137 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Wed, 24 Apr 2013 14:00:28 +0200 Subject: Cocoa: Improve text heuristic menu item syncing logic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Don't try anything after the original syncing, particularly after changing the menu item's text. Also, don't try anything if the menu item cannot be linked up to a menubar (see QTBUG-30756). This latter point requires extra syncing after adding a menu in the menubar. Finally, to be able to find the menubar, we need to clean the code for moc's eyes. Task-number: QTBUG-30756 Task-number: QTBUG-30812 Change-Id: I88fad663f1c35d03a0cb167d1723d16f590918c0 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoamenu.h | 5 +---- src/plugins/platforms/cocoa/qcocoamenu.mm | 15 +++++++++++++-- src/plugins/platforms/cocoa/qcocoamenubar.h | 3 +-- src/plugins/platforms/cocoa/qcocoamenubar.mm | 5 ++++- src/plugins/platforms/cocoa/qcocoamenuitem.h | 13 +++++++++++-- src/plugins/platforms/cocoa/qcocoamenuitem.mm | 23 +++++++++++++++++++++-- 6 files changed, 51 insertions(+), 13 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoamenu.h b/src/plugins/platforms/cocoa/qcocoamenu.h index 65f31a33c2..9100b9b15f 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.h +++ b/src/plugins/platforms/cocoa/qcocoamenu.h @@ -47,10 +47,6 @@ #include #include "qcocoamenuitem.h" -@class NSMenuItem; -@class NSMenu; -@class NSObject; - QT_BEGIN_NAMESPACE class QCocoaMenu : public QPlatformMenu @@ -89,6 +85,7 @@ public: virtual QPlatformMenuItem *menuItemAt(int position) const; virtual QPlatformMenuItem *menuItemForTag(quintptr tag) const; + QList items() const; QList merged() const; private: QCocoaMenuItem *itemOrNull(int index) const; diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm index df338a1109..9020aef600 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.mm +++ b/src/plugins/platforms/cocoa/qcocoamenu.mm @@ -271,8 +271,11 @@ void QCocoaMenu::syncSeparatorsCollapsible(bool enable) NSArray *itemArray = [m_nativeMenu itemArray]; for (unsigned int i = 0; i < [itemArray count]; ++i) { NSMenuItem *item = reinterpret_cast([itemArray objectAtIndex:i]); - if ([item isSeparatorItem]) + if ([item isSeparatorItem]) { + QCocoaMenuItem *cocoaItem = reinterpret_cast([item tag]); + cocoaItem->setVisible(!previousIsSeparator); [item setHidden:previousIsSeparator]; + } if (![item isHidden]) { previousItem = item; @@ -281,8 +284,11 @@ void QCocoaMenu::syncSeparatorsCollapsible(bool enable) } // We now need to check the final item since we don't want any separators at the end of the list. - if (previousItem && previousIsSeparator) + if (previousItem && previousIsSeparator) { + QCocoaMenuItem *cocoaItem = reinterpret_cast([previousItem tag]); + cocoaItem->setVisible(false); [previousItem setHidden:YES]; + } } else { foreach (QCocoaMenuItem *item, m_menuItems) { if (!item->isSeparator()) @@ -378,6 +384,11 @@ QPlatformMenuItem *QCocoaMenu::menuItemForTag(quintptr tag) const return 0; } +QList QCocoaMenu::items() const +{ + return m_menuItems; +} + QList QCocoaMenu::merged() const { QList result; diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.h b/src/plugins/platforms/cocoa/qcocoamenubar.h index 2db2abcaaf..8086676cc5 100644 --- a/src/plugins/platforms/cocoa/qcocoamenubar.h +++ b/src/plugins/platforms/cocoa/qcocoamenubar.h @@ -47,14 +47,13 @@ #include #include "qcocoamenu.h" -@class NSMenu; - QT_BEGIN_NAMESPACE class QCocoaWindow; class QCocoaMenuBar : public QPlatformMenuBar { + Q_OBJECT public: QCocoaMenuBar(); virtual ~QCocoaMenuBar(); diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.mm b/src/plugins/platforms/cocoa/qcocoamenubar.mm index b0a53244f4..b112e40549 100644 --- a/src/plugins/platforms/cocoa/qcocoamenubar.mm +++ b/src/plugins/platforms/cocoa/qcocoamenubar.mm @@ -110,6 +110,7 @@ void QCocoaMenuBar::insertMenu(QPlatformMenu *platformMenu, QPlatformMenu *befor } platformMenu->setParent(this); + syncMenu(platformMenu); [m_nativeMenu setSubmenu: menu->nsMenu() forItem: menu->nsMenuItem()]; } @@ -132,7 +133,9 @@ void QCocoaMenuBar::removeMenu(QPlatformMenu *platformMenu) void QCocoaMenuBar::syncMenu(QPlatformMenu *menu) { - Q_UNUSED(menu); + QCocoaMenu *cocoaMenu = static_cast(menu); + Q_FOREACH (QCocoaMenuItem *item, cocoaMenu->items()) + cocoaMenu->syncMenuItem(item); } void QCocoaMenuBar::handleReparent(QWindow *newParentWindow) diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.h b/src/plugins/platforms/cocoa/qcocoamenuitem.h index 0e6d17343d..1e69ed5a4b 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuitem.h +++ b/src/plugins/platforms/cocoa/qcocoamenuitem.h @@ -48,8 +48,16 @@ //#define QT_COCOA_ENABLE_MENU_DEBUG -@class NSMenuItem; -@class NSMenu; +#ifdef __OBJC__ +#define QT_FORWARD_DECLARE_OBJC_CLASS(__KLASS__) @class __KLASS__ +#else +#define QT_FORWARD_DECLARE_OBJC_CLASS(__KLASS__) typedef struct objc_object __KLASS__ +#endif + +QT_FORWARD_DECLARE_OBJC_CLASS(NSMenuItem); +QT_FORWARD_DECLARE_OBJC_CLASS(NSMenu); +QT_FORWARD_DECLARE_OBJC_CLASS(NSObject); + QT_BEGIN_NAMESPACE @@ -96,6 +104,7 @@ private: NSMenuItem *m_native; QString m_text; + bool m_textSynced; QIcon m_icon; QCocoaMenu *m_menu; bool m_isVisible; diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm index 51d9a83345..1255f75eb7 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm +++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm @@ -42,6 +42,7 @@ #include "qcocoamenuitem.h" #include "qcocoamenu.h" +#include "qcocoamenubar.h" #include "messages.h" #include "qcocoahelpers.h" #include "qcocoaautoreleasepool.h" @@ -90,6 +91,7 @@ NSUInteger keySequenceModifierMask(const QKeySequence &accel) QCocoaMenuItem::QCocoaMenuItem() : m_native(NULL), + m_textSynced(false), m_menu(NULL), m_isVisible(true), m_enabled(true), @@ -156,6 +158,8 @@ void QCocoaMenuItem::setFont(const QFont &font) void QCocoaMenuItem::setRole(MenuRole role) { + if (role != m_role) + m_textSynced = false; // Changing role deserves a second chance. m_role = role; } @@ -193,7 +197,7 @@ NSMenuItem *QCocoaMenuItem::sync() } } - if ((m_role != NoRole) || m_merged) { + if ((m_role != NoRole && !m_textSynced) || m_merged) { NSMenuItem *mergeItem = nil; QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader(); switch (m_role) { @@ -212,7 +216,17 @@ NSMenuItem *QCocoaMenuItem::sync() case PreferencesRole: mergeItem = [loader preferencesMenuItem]; break; - case TextHeuristicRole: + case TextHeuristicRole: { + QObject *p = parent(); + int depth = 1; + QCocoaMenuBar *menubar = 0; + while (depth < 3 && p && !(menubar = qobject_cast(p))) { + ++depth; + p = p->parent(); + } + if (depth == 3 || !menubar) + break; // Menu item too deep in the hierarchy, or not connected to any menubar + switch (detectMenuRole(m_text)) { case QPlatformMenuItem::AboutRole: if (m_text.indexOf(QRegExp(QString::fromLatin1("qt$"), Qt::CaseInsensitive)) == -1) @@ -227,15 +241,18 @@ NSMenuItem *QCocoaMenuItem::sync() mergeItem = [loader quitMenuItem]; break; default: + m_textSynced = true; break; } break; + } default: qWarning() << Q_FUNC_INFO << "unsupported role" << (int) m_role; } if (mergeItem) { + m_textSynced = true; m_merged = true; [mergeItem retain]; [m_native release]; @@ -247,6 +264,8 @@ NSMenuItem *QCocoaMenuItem::sync() m_native = nil; // create item below m_merged = false; } + } else { + m_textSynced = true; // NoRole, and that was set explicitly. So, nothing to do anymore. } if (!m_native) { -- cgit v1.2.3 From 38608486744cbecafb63c0609635102a1671fe8d Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 24 Apr 2013 11:47:24 +0200 Subject: Windows: Update transient parent in show(). Similar to XCB. Task-number: QTBUG-30707 Change-Id: I6dd7aa370891a46aa5a2243528692180d8366486 Reviewed-by: Joerg Bornemann --- .../platforms/windows/qtwindows_additional.h | 4 ++ src/plugins/platforms/windows/qwindowswindow.cpp | 47 ++++++++++++++++------ src/plugins/platforms/windows/qwindowswindow.h | 1 + 3 files changed, 39 insertions(+), 13 deletions(-) diff --git a/src/plugins/platforms/windows/qtwindows_additional.h b/src/plugins/platforms/windows/qtwindows_additional.h index 3b2e9787a2..49ddf3106b 100644 --- a/src/plugins/platforms/windows/qtwindows_additional.h +++ b/src/plugins/platforms/windows/qtwindows_additional.h @@ -49,6 +49,10 @@ # define WM_THEMECHANGED 0x031A #endif +#ifndef GWL_HWNDPARENT +# define GWL_HWNDPARENT (-8) +#endif + /* Complement the definitions and declarations missing * when using MinGW or older Windows SDKs. */ diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 1ff98a3d29..010197d6d8 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -1013,6 +1013,24 @@ QPoint QWindowsWindow::mapFromGlobal(const QPoint &pos) const return pos; } +// Update the transient parent for a toplevel window. The concept does not +// really exist on Windows, the relationship is set by passing a parent along with !WS_CHILD +// to window creation or by setting the parent using GWL_HWNDPARENT (as opposed to +// SetParent, which would make it a real child). +void QWindowsWindow::updateTransientParent() const +{ +#ifndef Q_OS_WINCE + // Update transient parent. + const HWND oldTransientParent = + GetAncestor(m_data.hwnd, GA_PARENT) == GetDesktopWindow() ? GetAncestor(m_data.hwnd, GA_ROOTOWNER) : HWND(0); + HWND newTransientParent = 0; + if (const QWindow *tp = window()->transientParent()) + newTransientParent = QWindowsWindow::handleOf(tp); + if (newTransientParent && newTransientParent != oldTransientParent) + SetWindowLongPtr(m_data.hwnd, GWL_HWNDPARENT, (LONG_PTR)newTransientParent); +#endif // !Q_OS_WINCE +} + // partially from QWidgetPrivate::show_sys() void QWindowsWindow::show_sys() const { @@ -1027,19 +1045,22 @@ void QWindowsWindow::show_sys() const sm = SW_SHOWMINIMIZED; if (!isVisible()) sm = SW_SHOWMINNOACTIVE; - } else if (state & Qt::WindowMaximized) { - sm = SW_SHOWMAXIMIZED; - // Windows will not behave correctly when we try to maximize a window which does not - // have minimize nor maximize buttons in the window frame. Windows would then ignore - // non-available geometry, and rather maximize the widget to the full screen, minus the - // window frame (caption). So, we do a trick here, by adding a maximize button before - // maximizing the widget, and then remove the maximize button afterwards. - if (flags & Qt::WindowTitleHint && - !(flags & (Qt::WindowMinMaxButtonsHint | Qt::FramelessWindowHint))) { - fakedMaximize = TRUE; - setStyle(style() | WS_MAXIMIZEBOX); - } - } + } else { + updateTransientParent(); + if (state & Qt::WindowMaximized) { + sm = SW_SHOWMAXIMIZED; + // Windows will not behave correctly when we try to maximize a window which does not + // have minimize nor maximize buttons in the window frame. Windows would then ignore + // non-available geometry, and rather maximize the widget to the full screen, minus the + // window frame (caption). So, we do a trick here, by adding a maximize button before + // maximizing the widget, and then remove the maximize button afterwards. + if (flags & Qt::WindowTitleHint && + !(flags & (Qt::WindowMinMaxButtonsHint | Qt::FramelessWindowHint))) { + fakedMaximize = TRUE; + setStyle(style() | WS_MAXIMIZEBOX); + } + } // Qt::WindowMaximized + } // !Qt::WindowMinimized } if (type == Qt::Popup || type == Qt::ToolTip || type == Qt::Tool) sm = SW_SHOWNOACTIVATE; diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h index fed9d089df..6c735ede7d 100644 --- a/src/plugins/platforms/windows/qwindowswindow.h +++ b/src/plugins/platforms/windows/qwindowswindow.h @@ -272,6 +272,7 @@ private: inline bool isFullScreen_sys() const; inline void setWindowState_sys(Qt::WindowState newState); inline void setParent_sys(const QPlatformWindow *parent) const; + inline void updateTransientParent() const; void destroyWindow(); void registerDropSite(); void unregisterDropSite(); -- cgit v1.2.3 From b06b51975929f56c37203ddc77379417a933384f Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Wed, 24 Apr 2013 22:50:53 +0200 Subject: Respect the hotspot when creating the cursor in Cocoa MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The hotspot was not taken from the QCursor so if one was set then it was reset to 0x0. Change-Id: Ie81f1c2ac15a16f10436738367e612c44dc42d38 Reviewed-by: Friedemann Kleint Reviewed-by: Richard Moe Gustavsen Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoacursor.mm | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoacursor.mm b/src/plugins/platforms/cocoa/qcocoacursor.mm index 12808b7041..e5b41e7a88 100644 --- a/src/plugins/platforms/cocoa/qcocoacursor.mm +++ b/src/plugins/platforms/cocoa/qcocoacursor.mm @@ -199,14 +199,14 @@ NSCursor *QCocoaCursor::createCursorData(QCursor *cursor) #endif const uchar *cursorData = 0; const uchar *cursorMaskData = 0; - QPoint hotspot; + QPoint hotspot = cursor->hotSpot(); switch (cursor->shape()) { case Qt::BitmapCursor: { if (cursor->pixmap().isNull()) - return createCursorFromBitmap(cursor->bitmap(), cursor->mask()); + return createCursorFromBitmap(cursor->bitmap(), cursor->mask(), hotspot); else - return createCursorFromPixmap(cursor->pixmap()); + return createCursorFromPixmap(cursor->pixmap(), hotspot); break; } case Qt::BlankCursor: { QPixmap pixmap = QPixmap(16, 16); @@ -215,19 +215,19 @@ NSCursor *QCocoaCursor::createCursorData(QCursor *cursor) break; } case Qt::WaitCursor: { QPixmap pixmap = QPixmap(QLatin1String(":/qt-project.org/mac/cursors/images/spincursor.png")); - return createCursorFromPixmap(pixmap); + return createCursorFromPixmap(pixmap, hotspot); break; } case Qt::SizeAllCursor: { QPixmap pixmap = QPixmap(QLatin1String(":/qt-project.org/mac/cursors/images/pluscursor.png")); - return createCursorFromPixmap(pixmap); + return createCursorFromPixmap(pixmap, hotspot); break; } case Qt::BusyCursor: { QPixmap pixmap = QPixmap(QLatin1String(":/qt-project.org/mac/cursors/images/waitcursor.png")); - return createCursorFromPixmap(pixmap); + return createCursorFromPixmap(pixmap, hotspot); break; } case Qt::ForbiddenCursor: { QPixmap pixmap = QPixmap(QLatin1String(":/qt-project.org/mac/cursors/images/forbiddencursor.png")); - return createCursorFromPixmap(pixmap); + return createCursorFromPixmap(pixmap, hotspot); break; } #define QT_USE_APPROXIMATE_CURSORS #ifdef QT_USE_APPROXIMATE_CURSORS -- cgit v1.2.3 From 89e2319322e2e29d6297e72431c9327358e3be21 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Mon, 22 Apr 2013 23:28:06 +0200 Subject: Don't do any transitions if the widget is disabled On Windows 8 it would end up changing the look of the QLineEdit when the mouse hovered over it even though it was not enabled. None of the Windows platforms show the lineedit changing when hovered over if it is disabled so we can skip the whole thing. Task-number: QTBUG-29224 Change-Id: Ib9495bf395477f114e91b744e1b1209c9e11f336 Reviewed-by: J-P Nurmi --- src/widgets/styles/qwindowsvistastyle.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/styles/qwindowsvistastyle.cpp b/src/widgets/styles/qwindowsvistastyle.cpp index f65e52305c..b08eab580d 100644 --- a/src/widgets/styles/qwindowsvistastyle.cpp +++ b/src/widgets/styles/qwindowsvistastyle.cpp @@ -314,7 +314,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt return; } - if (d->transitionsEnabled() && canAnimate(option)) { + if ((option->state & State_Enabled) && d->transitionsEnabled() && canAnimate(option)) { { QRect oldRect; QRect newRect; -- cgit v1.2.3 From 8f125985dbebef9ab9db31e8a180d01b7452030e Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Thu, 4 Apr 2013 08:45:50 +0200 Subject: Cleanup the SQL tests This removes some XFAILS that were no longer correct and fixes some existing problems in the tests where ODBC is concerned. Change-Id: I91de526bb50ad4046ba07ddb5336aa3714966687 Reviewed-by: Mark Brand Reviewed-by: Caroline Chao --- tests/auto/sql/kernel/qsqldatabase/tst_databases.h | 70 +++--- .../sql/kernel/qsqldatabase/tst_qsqldatabase.cpp | 186 ++++++++-------- .../auto/sql/kernel/qsqldriver/tst_qsqldriver.cpp | 47 ++-- tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp | 245 ++++++++++----------- .../models/qsqlquerymodel/tst_qsqlquerymodel.cpp | 12 +- .../tst_qsqlrelationaltablemodel.cpp | 81 ++++--- .../models/qsqltablemodel/tst_qsqltablemodel.cpp | 9 +- tests/benchmarks/sql/kernel/qsqlquery/main.cpp | 32 +-- 8 files changed, 342 insertions(+), 340 deletions(-) diff --git a/tests/auto/sql/kernel/qsqldatabase/tst_databases.h b/tests/auto/sql/kernel/qsqldatabase/tst_databases.h index e47140b61b..af3c5b2e90 100644 --- a/tests/auto/sql/kernel/qsqldatabase/tst_databases.h +++ b/tests/auto/sql/kernel/qsqldatabase/tst_databases.h @@ -108,14 +108,21 @@ inline QString fixupTableName(const QString &tableName, QSqlDatabase db) inline static QString qTableName(const QString& prefix, const char *sourceFileName, QSqlDatabase db) { - return fixupTableName(QString(QLatin1String("dbtst") + QString::number(qHash(QLatin1String(sourceFileName) + + QString tableStr = QLatin1String("dbtst"); + if (db.driverName().toLower().contains("ODBC")) + tableStr += QLatin1String("_odbc"); + return fixupTableName(QString(QLatin1String("dbtst") + db.driverName() + + QString::number(qHash(QLatin1String(sourceFileName) + "_" + qGetHostName().replace( "-", "_" )), 16) + "_" + prefix), db); } inline static QString qTableName(const QString& prefix, QSqlDatabase db) { - return fixupTableName(QString(db.driver()->escapeIdentifier(prefix + "_" + qGetHostName(), QSqlDriver::TableName)), - db); + QString tableStr; + if (db.driverName().toLower().contains("ODBC")) + tableStr += QLatin1String("_odbc"); + return fixupTableName(QString(db.driver()->escapeIdentifier(prefix + tableStr + "_" + + qGetHostName(), QSqlDriver::TableName)),db); } inline static bool testWhiteSpaceNames( const QString &name ) @@ -240,6 +247,7 @@ public: void addDbs() { + //addDb("QOCI", "localhost", "system", "penandy"); // addDb( "QOCI8", "//horsehead.nokia.troll.no:1521/pony.troll.no", "scott", "tiger" ); // Oracle 9i on horsehead // addDb( "QOCI8", "//horsehead.nokia.troll.no:1521/ustest.troll.no", "scott", "tiger", "" ); // Oracle 9i on horsehead // addDb( "QOCI8", "//iceblink.nokia.troll.no:1521/ice.troll.no", "scott", "tiger", "" ); // Oracle 8 on iceblink (not currently working) @@ -372,7 +380,7 @@ public: bool wasDropped; QSqlQuery q( db ); QStringList dbtables=db.tables(); - + QSqlDriverPrivate::DBMSType dbType = getDatabaseType(db); foreach(const QString &tableName, tableNames) { wasDropped = true; @@ -384,7 +392,7 @@ public: foreach(const QString &table2, dbtables.filter(table, Qt::CaseInsensitive)) { if(table2.compare(table.section('.', -1, -1), Qt::CaseInsensitive) == 0) { table=db.driver()->escapeIdentifier(table2, QSqlDriver::TableName); - if(isPostgreSQL(db)) + if (dbType == QSqlDriverPrivate::PostgreSQL) wasDropped = q.exec( "drop table " + table + " cascade"); else wasDropped = q.exec( "drop table " + table); @@ -449,25 +457,26 @@ public: // blobSize is only used if the db doesn't have a generic blob type static QString blobTypeName( QSqlDatabase db, int blobSize = 10000 ) { - if ( db.driverName().startsWith( "QMYSQL" ) ) + const QSqlDriverPrivate::DBMSType dbType = getDatabaseType(db); + if (dbType == QSqlDriverPrivate::MySqlServer) return "longblob"; - if ( db.driverName().startsWith( "QPSQL" ) ) + if (dbType == QSqlDriverPrivate::PostgreSQL) return "bytea"; - if ( db.driverName().startsWith( "QTDS" ) - || isSqlServer( db ) + if (dbType == QSqlDriverPrivate::Sybase + || dbType == QSqlDriverPrivate::MSSqlServer || isMSAccess( db ) ) return "image"; - if ( db.driverName().startsWith( "QDB2" ) ) + if (dbType == QSqlDriverPrivate::DB2) return QString( "blob(%1)" ).arg( blobSize ); - if ( db.driverName().startsWith( "QIBASE" ) ) + if (dbType == QSqlDriverPrivate::Interbase) return QString( "blob sub_type 0 segment size 4096" ); - if ( db.driverName().startsWith( "QOCI" ) - || db.driverName().startsWith( "QSQLITE" ) ) + if (dbType == QSqlDriverPrivate::Oracle + || dbType == QSqlDriverPrivate::SQLite) return "blob"; qDebug() << "tst_Databases::blobTypeName: Don't know the blob type for" << dbToString( db ); @@ -477,22 +486,24 @@ public: static QString dateTimeTypeName(QSqlDatabase db) { - if (db.driverName().startsWith("QPSQL")) + const QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); + if (dbType == QSqlDriverPrivate::PostgreSQL) return QLatin1String("timestamp"); - if (db.driverName().startsWith("QOCI") && getOraVersion(db) >= 9) + if (dbType == QSqlDriverPrivate::Oracle && getOraVersion(db) >= 9) return QLatin1String("timestamp(0)"); return QLatin1String("datetime"); } static QString autoFieldName( QSqlDatabase db ) { - if ( db.driverName().startsWith( "QMYSQL" ) ) + const QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); + if (dbType == QSqlDriverPrivate::MySqlServer) return "AUTO_INCREMENT"; - if ( db.driverName().startsWith( "QTDS" ) ) + if (dbType == QSqlDriverPrivate::Sybase || dbType == QSqlDriverPrivate::MSSqlServer) return "IDENTITY"; -/* if ( db.driverName().startsWith( "QPSQL" ) ) +/* if (dbType == QSqlDriverPrivate::PostgreSQL) return "SERIAL";*/ -// if ( db.driverName().startsWith( "QDB2" ) ) +// if (dbType == QSqlDriverPrivate::DB2) // return "GENERATED BY DEFAULT AS IDENTITY"; return QString(); @@ -522,10 +533,10 @@ public: return result.toLocal8Bit(); } - static bool isSqlServer( QSqlDatabase db ) + static QSqlDriverPrivate::DBMSType getDatabaseType(QSqlDatabase db) { QSqlDriverPrivate *d = static_cast(QObjectPrivate::get(db.driver())); - return d->dbmsType == QSqlDriverPrivate::MSSqlServer; + return d->dbmsType; } static bool isMSAccess( QSqlDatabase db ) @@ -533,23 +544,6 @@ public: return db.databaseName().contains( "Access Driver", Qt::CaseInsensitive ); } - static bool isPostgreSQL( QSqlDatabase db ) - { - QSqlDriverPrivate *d = static_cast(QObjectPrivate::get(db.driver())); - return d->dbmsType == QSqlDriverPrivate::PostgreSQL; - } - - static bool isMySQL( QSqlDatabase db ) - { - QSqlDriverPrivate *d = static_cast(QObjectPrivate::get(db.driver())); - return d->dbmsType == QSqlDriverPrivate::MySqlServer; - } - static bool isDB2( QSqlDatabase db ) - { - QSqlDriverPrivate *d = static_cast(QObjectPrivate::get(db.driver())); - return d->dbmsType == QSqlDriverPrivate::DB2; - } - // -1 on fail, else Oracle version static int getOraVersion( QSqlDatabase db ) { diff --git a/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp b/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp index b958a30108..91ed7360c3 100644 --- a/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp +++ b/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp @@ -145,8 +145,8 @@ private slots: void psql_escapedIdentifiers(); void psql_escapeBytea_data() { generic_data("QPSQL"); } void psql_escapeBytea(); - void bug_249059_data() { generic_data("QPSQL"); } - void bug_249059(); + void psql_bug249059_data() { generic_data("QPSQL"); } + void psql_bug249059(); void mysqlOdbc_unsignedIntegers_data() { generic_data(); } void mysqlOdbc_unsignedIntegers(); @@ -242,14 +242,16 @@ struct FieldDef { // excluding the primary key field static int createFieldTable(const FieldDef fieldDefs[], QSqlDatabase db) { - tst_Databases::safeDropTable(db, qTableName("qtestfields", __FILE__, db)); + QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); + const QString tableName = qTableName("qtestfields", __FILE__, db); + tst_Databases::safeDropTable(db, tableName); QSqlQuery q(db); // construct a create table statement consisting of all fieldtypes - QString qs = "create table " + qTableName("qtestfields", __FILE__, db); + QString qs = "create table " + tableName; QString autoName = tst_Databases::autoFieldName(db); if (tst_Databases::isMSAccess(db)) qs.append(" (id int not null"); - else if (tst_Databases::isPostgreSQL(db)) + else if (dbType == QSqlDriverPrivate::PostgreSQL) qs.append(" (id serial not null"); else qs.append(QString("(id integer not null %1 primary key").arg(autoName)); @@ -257,9 +259,8 @@ static int createFieldTable(const FieldDef fieldDefs[], QSqlDatabase db) int i = 0; for (i = 0; !fieldDefs[ i ].typeName.isNull(); ++i) { qs += QString(",\n %1 %2").arg(fieldDefs[ i ].fieldName()).arg(fieldDefs[ i ].typeName); - if ((db.driverName().startsWith("QTDS") || tst_Databases::isSqlServer(db)) && fieldDefs[ i ].nullable) { + if ((dbType == QSqlDriverPrivate::Sybase || dbType == QSqlDriverPrivate::MSSqlServer) && fieldDefs[i].nullable) qs += " null"; - } } if (tst_Databases::isMSAccess(db)) @@ -286,31 +287,33 @@ void tst_QSqlDatabase::createTestTables(QSqlDatabase db) { if (!db.isValid()) return; + const QString tableName = qTableName("qtest", __FILE__, db); QSqlQuery q(db); - if (db.driverName().startsWith("QMYSQL")) + QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); + if (dbType == QSqlDriverPrivate::MySqlServer) { // ### stupid workaround until we find a way to hardcode this // in the MySQL server startup script q.exec("set table_type=innodb"); - else if (tst_Databases::isSqlServer(db)) { + } else if (dbType == QSqlDriverPrivate::MSSqlServer) { QVERIFY_SQL(q, exec("SET ANSI_DEFAULTS ON")); QVERIFY_SQL(q, exec("SET IMPLICIT_TRANSACTIONS OFF")); - } else if(tst_Databases::isPostgreSQL(db)) + } else if (dbType == QSqlDriverPrivate::PostgreSQL) { QVERIFY_SQL( q, exec("set client_min_messages='warning'")); - + } // please never ever change this table; otherwise fix all tests ;) if (tst_Databases::isMSAccess(db)) { - QVERIFY_SQL(q, exec("create table " + qTableName("qtest", __FILE__, db) + + QVERIFY_SQL(q, exec("create table " + tableName + " (id int not null, t_varchar varchar(40) not null, t_char char(40), " "t_numeric number, primary key (id, t_varchar))")); } else { - QVERIFY_SQL(q, exec("create table " + qTableName("qtest", __FILE__, db) + + QVERIFY_SQL(q, exec("create table " + tableName + " (id integer not null, t_varchar varchar(40) not null, " "t_char char(40), t_numeric numeric(6, 3), primary key (id, t_varchar))")); } if (testWhiteSpaceNames(db.driverName())) { QString qry = "create table " - + db.driver()->escapeIdentifier(qTableName("qtest", __FILE__, db) + " test", QSqlDriver::TableName) + + db.driver()->escapeIdentifier(tableName + " test", QSqlDriver::TableName) + '(' + db.driver()->escapeIdentifier(QLatin1String("test test"), QSqlDriver::FieldName) + " int not null primary key)"; @@ -323,16 +326,17 @@ void tst_QSqlDatabase::dropTestTables(QSqlDatabase db) if (!db.isValid()) return; - if(tst_Databases::isPostgreSQL(db)) { + QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); + if (dbType == QSqlDriverPrivate::PostgreSQL) { QSqlQuery q(db); QVERIFY_SQL( q, exec("set client_min_messages='warning'")); } // drop the view first, otherwise we'll get dependency problems tst_Databases::safeDropViews(db, QStringList() << qTableName("qtest_view", __FILE__, db) << qTableName("qtest_view2", __FILE__, db)); - + const QString qtestTable = qTableName("qtest", __FILE__, db); QStringList tableNames; - tableNames << qTableName("qtest", __FILE__, db) + tableNames << qtestTable << qTableName("qtestfields", __FILE__, db) << qTableName("qtestalter", __FILE__, db) << qTableName("qtest_temp", __FILE__, db) @@ -354,17 +358,17 @@ void tst_QSqlDatabase::dropTestTables(QSqlDatabase db) << qTableName("bug_249059", __FILE__, db); QSqlQuery q(0, db); - if (db.driverName().startsWith("QPSQL")) { + if (dbType == QSqlDriverPrivate::PostgreSQL) { q.exec("drop schema " + qTableName("qtestschema", __FILE__, db) + " cascade"); q.exec("drop schema " + qTableName("qtestScHeMa", __FILE__, db) + " cascade"); } if (testWhiteSpaceNames(db.driverName())) - tableNames << db.driver()->escapeIdentifier(qTableName("qtest", __FILE__, db) + " test", QSqlDriver::TableName); + tableNames << db.driver()->escapeIdentifier(qtestTable + " test", QSqlDriver::TableName); tst_Databases::safeDropTables(db, tableNames); - if (db.driverName().startsWith("QOCI")) { + if (dbType == QSqlDriverPrivate::Oracle) { q.exec("drop user "+qTableName("CREATOR", __FILE__, db)+ " cascade"); q.exec("drop user "+qTableName("APPUSER", __FILE__, db) + " cascade"); q.exec("DROP TABLE sys."+qTableName("mypassword", __FILE__, db)); @@ -489,7 +493,8 @@ void tst_QSqlDatabase::open() QVERIFY(!db.isOpenError()); } - if (db.driverName().startsWith("QSQLITE") && db.databaseName() == ":memory:") { + QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); + if (dbType == QSqlDriverPrivate::SQLite && db.databaseName() == ":memory:") { // tables in in-memory databases don't survive an open/close createTestTables(db); populateTestTables(db); @@ -501,6 +506,7 @@ void tst_QSqlDatabase::tables() QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); + QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); const QString qtest(qTableName("qtest", __FILE__, db)), qtest_view(qTableName("qtest_view", __FILE__, db)), temp_tab(qTableName("test_tab", __FILE__, db)); @@ -555,9 +561,8 @@ void tst_QSqlDatabase::tables() QVERIFY(tables.contains(temp_tab, Qt::CaseInsensitive)); QVERIFY(tables.contains(qtest, Qt::CaseInsensitive)); - if (db.driverName().startsWith("QPSQL")) { + if (dbType == QSqlDriverPrivate::PostgreSQL) QVERIFY(tables.contains(qtest + " test")); - } } void tst_QSqlDatabase::whitespaceInIdentifiers() @@ -565,6 +570,7 @@ void tst_QSqlDatabase::whitespaceInIdentifiers() QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); + const QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); if (testWhiteSpaceNames(db.driverName())) { const QString tableName(qTableName("qtest", __FILE__, db) + " test"); @@ -573,7 +579,7 @@ void tst_QSqlDatabase::whitespaceInIdentifiers() QSqlRecord rec = db.record(db.driver()->escapeIdentifier(tableName, QSqlDriver::TableName)); QCOMPARE(rec.count(), 1); QCOMPARE(rec.fieldName(0), QString("test test")); - if(db.driverName().startsWith("QOCI")) + if (dbType == QSqlDriverPrivate::Oracle) QCOMPARE(rec.field(0).type(), QVariant::Double); else QCOMPARE(rec.field(0).type(), QVariant::Int); @@ -581,7 +587,7 @@ void tst_QSqlDatabase::whitespaceInIdentifiers() QSqlIndex idx = db.primaryIndex(db.driver()->escapeIdentifier(tableName, QSqlDriver::TableName)); QCOMPARE(idx.count(), 1); QCOMPARE(idx.fieldName(0), QString("test test")); - if(db.driverName().startsWith("QOCI")) + if (dbType == QSqlDriverPrivate::Oracle) QCOMPARE(idx.field(0).type(), QVariant::Double); else QCOMPARE(idx.field(0).type(), QVariant::Int); @@ -670,13 +676,13 @@ void tst_QSqlDatabase::testRecord(const FieldDef fieldDefs[], const QSqlRecord& void tst_QSqlDatabase::commonFieldTest(const FieldDef fieldDefs[], QSqlDatabase db, const int fieldCount) { CHECK_DATABASE(db); - - QSqlRecord rec = db.record(qTableName("qtestfields", __FILE__, db)); + const QString tableName = qTableName("qtestfields", __FILE__, db); + QSqlRecord rec = db.record(tableName); QCOMPARE((int)rec.count(), fieldCount+1); testRecord(fieldDefs, rec, db); QSqlQuery q(db); - QVERIFY_SQL(q, exec("select * from " + qTableName("qtestfields", __FILE__, db))); + QVERIFY_SQL(q, exec("select * from " + tableName)); } void tst_QSqlDatabase::recordTDS() @@ -772,12 +778,13 @@ void tst_QSqlDatabase::recordOCI() commonFieldTest(fieldDefs, db, fieldCount); // some additional tests - QSqlRecord rec = db.record(qTableName("qtestfields", __FILE__, db)); + const QString tableName = qTableName("qtestfields", __FILE__, db); + QSqlRecord rec = db.record(tableName); QCOMPARE(rec.field("T_NUMBER").length(), 10); QCOMPARE(rec.field("T_NUMBER").precision(), 5); QSqlQuery q(db); - QVERIFY_SQL(q, exec("SELECT * FROM " + qTableName("qtestfields", __FILE__, db))); + QVERIFY_SQL(q, exec("SELECT * FROM " + tableName)); rec = q.record(); QCOMPARE(rec.field("T_NUMBER").length(), 10); QCOMPARE(rec.field("T_NUMBER").precision(), 5); @@ -831,14 +838,15 @@ void tst_QSqlDatabase::recordPSQL() QSqlQuery q(db); - if(tst_Databases::isPostgreSQL(db)) + QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); + if (dbType == QSqlDriverPrivate::PostgreSQL) QVERIFY_SQL( q, exec("set client_min_messages='warning'")); - - q.exec("drop sequence " + qTableName("qtestfields", __FILE__, db) + "_t_bigserial_seq"); - q.exec("drop sequence " + qTableName("qtestfields", __FILE__, db) + "_t_serial_seq"); + const QString tableName = qTableName("qtestfields", __FILE__, db); + q.exec("drop sequence " + tableName + "_t_bigserial_seq"); + q.exec("drop sequence " + tableName + "_t_serial_seq"); // older psql cut off the table name - q.exec("drop sequence " + qTableName("qtestfields", __FILE__, db).left(15) + "_t_bigserial_seq"); - q.exec("drop sequence " + qTableName("qtestfields", __FILE__, db).left(18) + "_t_serial_seq"); + q.exec("drop sequence " + tableName + "_t_bigserial_seq"); + q.exec("drop sequence " + tableName + "_t_serial_seq"); const int fieldCount = createFieldTable(fieldDefs, db); QVERIFY(fieldCount > 0); @@ -1017,7 +1025,8 @@ void tst_QSqlDatabase::recordSQLServer() QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); - if (!tst_Databases::isSqlServer(db)) + QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); + if (dbType != QSqlDriverPrivate::MSSqlServer) QSKIP("SQL server specific test"); // ### TODO: Add the rest of the fields @@ -1075,6 +1084,7 @@ void tst_QSqlDatabase::transaction() QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); + const QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); const QString qtest(qTableName("qtest", __FILE__, db)); if (!db.driver()->hasFeature(QSqlDriver::Transactions)) @@ -1105,15 +1115,13 @@ void tst_QSqlDatabase::transaction() QCOMPARE(q.value(0).toInt(), 41); q.clear(); // for SQLite which does not allow any references on rows that shall be rolled back if (!db.rollback()) { - if (db.driverName().startsWith("QMYSQL")) + if (dbType == QSqlDriverPrivate::MySqlServer) QSKIP("MySQL transaction failed: " + tst_Databases::printError(db.lastError())); else QFAIL("Could not rollback transaction: " + tst_Databases::printError(db.lastError())); } QVERIFY_SQL(q, exec("select * from " + qtest + " where id = 41")); - if(db.driverName().startsWith("QODBC") && dbName.contains("MySQL")) - QEXPECT_FAIL("", "Some odbc drivers don't actually roll back despite telling us they do, especially the mysql driver", Continue); QVERIFY(!q.next()); populateTestTables(db); @@ -1124,23 +1132,24 @@ void tst_QSqlDatabase::bigIntField() QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); - QString drvName = db.driverName(); + const QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); const QString qtest_bigint(qTableName("qtest_bigint", __FILE__, db)); QSqlQuery q(db); q.setForwardOnly(true); - if (drvName.startsWith("QOCI")) + + if (dbType == QSqlDriverPrivate::Oracle) q.setNumericalPrecisionPolicy(QSql::LowPrecisionInt64); - if (drvName.startsWith("QMYSQL")) { + if (dbType == QSqlDriverPrivate::MySqlServer) { QVERIFY_SQL(q, exec("create table " + qtest_bigint + " (id int, t_s64bit bigint, t_u64bit bigint unsigned)")); - } else if (drvName.startsWith("QPSQL") - || drvName.startsWith("QDB2") - || tst_Databases::isSqlServer(db)) { + } else if (dbType == QSqlDriverPrivate::PostgreSQL + || dbType == QSqlDriverPrivate::DB2 + || dbType == QSqlDriverPrivate::MSSqlServer) { QVERIFY_SQL(q, exec("create table " + qtest_bigint + "(id int, t_s64bit bigint, t_u64bit bigint)")); - } else if (drvName.startsWith("QOCI")) { + } else if (dbType == QSqlDriverPrivate::Oracle) { QVERIFY_SQL(q, exec("create table " + qtest_bigint + " (id int, t_s64bit int, t_u64bit int)")); - //} else if (drvName.startsWith("QIBASE")) { + //} else if (dbType == QSqlDriverPrivate::Interbase) { // QVERIFY_SQL(q, exec("create table " + qtest_bigint + " (id int, t_s64bit int64, t_u64bit int64)")); } else { QSKIP("no 64 bit integer support"); @@ -1149,7 +1158,7 @@ void tst_QSqlDatabase::bigIntField() qlonglong ll = Q_INT64_C(9223372036854775807); qulonglong ull = Q_UINT64_C(18446744073709551615); - if (drvName.startsWith("QMYSQL") || drvName.startsWith("QOCI")) { + if (dbType == QSqlDriverPrivate::MySqlServer || dbType == QSqlDriverPrivate::Oracle) { q.bindValue(0, 0); q.bindValue(1, ll); q.bindValue(2, ull); @@ -1173,12 +1182,12 @@ void tst_QSqlDatabase::bigIntField() QVERIFY(q.next()); QCOMPARE(q.value(1).toDouble(), (double)ll); QCOMPARE(q.value(1).toLongLong(), ll); - if(drvName.startsWith("QOCI")) + if (dbType == QSqlDriverPrivate::Oracle) QEXPECT_FAIL("", "Oracle driver lacks support for unsigned int64 types", Continue); QCOMPARE(q.value(2).toULongLong(), ull); QVERIFY(q.next()); QCOMPARE(q.value(1).toLongLong(), -ll); - if(drvName.startsWith("QOCI")) + if (dbType == QSqlDriverPrivate::Oracle) QEXPECT_FAIL("", "Oracle driver lacks support for unsigned int64 types", Continue); QCOMPARE(q.value(2).toULongLong(), ull); } @@ -1188,12 +1197,11 @@ void tst_QSqlDatabase::caseSensivity() QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); + const QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); bool cs = false; - if (db.driverName().startsWith("QMYSQL") - || db.driverName().startsWith("QSQLITE") - || db.driverName().startsWith("QTDS") - || db.driverName().startsWith("QODBC")) + if (dbType == QSqlDriverPrivate::MySqlServer || dbType == QSqlDriverPrivate::SQLite || dbType == QSqlDriverPrivate::Sybase + || dbType == QSqlDriverPrivate::MSSqlServer || db.driverName().startsWith("QODBC")) cs = true; QSqlRecord rec = db.record(qTableName("qtest", __FILE__, db)); @@ -1222,7 +1230,8 @@ void tst_QSqlDatabase::noEscapedFieldNamesInRecord() CHECK_DATABASE(db); QString fieldname("t_varchar"); - if (db.driverName().startsWith("QOCI") || db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QDB2")) + QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); + if (dbType == QSqlDriverPrivate::Oracle || dbType == QSqlDriverPrivate::Interbase || dbType == QSqlDriverPrivate::DB2) fieldname = fieldname.toUpper(); QSqlQuery q(db); @@ -1241,14 +1250,12 @@ void tst_QSqlDatabase::psql_schemas() QSKIP("server does not support schemas"); QSqlQuery q(db); + QVERIFY_SQL( q, exec("set client_min_messages='warning'")); - if(tst_Databases::isPostgreSQL(db)) { - QVERIFY_SQL( q, exec("set client_min_messages='warning'")); - } + const QString schemaName = qTableName("qtestschema", __FILE__, db); + QVERIFY_SQL(q, exec("CREATE SCHEMA " + schemaName)); - QVERIFY_SQL(q, exec("CREATE SCHEMA " + qTableName("qtestschema", __FILE__, db))); - - QString table = qTableName("qtestschema", __FILE__, db) + '.' + qTableName("qtesttable", __FILE__, db); + QString table = schemaName + '.' + qTableName("qtesttable", __FILE__, db); QVERIFY_SQL(q, exec("CREATE TABLE " + table + " (id int primary key, name varchar(20))")); QVERIFY(db.tables().contains(table)); @@ -1274,9 +1281,7 @@ void tst_QSqlDatabase::psql_escapedIdentifiers() QSKIP("server does not support schemas"); QSqlQuery q(db); - - if(tst_Databases::isPostgreSQL(db)) - QVERIFY_SQL( q, exec("set client_min_messages='warning'")); + QVERIFY_SQL( q, exec("set client_min_messages='warning'")); const QString schemaName(qTableName("qtestScHeMa", __FILE__, db)), tableName(qTableName("qtest", __FILE__, db)), @@ -1339,7 +1344,7 @@ void tst_QSqlDatabase::psql_escapeBytea() QCOMPARE(i, 4); } -void tst_QSqlDatabase::bug_249059() +void tst_QSqlDatabase::psql_bug249059() { QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); @@ -1408,7 +1413,8 @@ void tst_QSqlDatabase::precisionPolicy() QString query = QString("SELECT num FROM %1 WHERE id = 1").arg(tableName); QVERIFY_SQL(q, exec(query)); QVERIFY_SQL(q, next()); - if(db.driverName().startsWith("QSQLITE")) + QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); + if (dbType == QSqlDriverPrivate::SQLite) QEXPECT_FAIL("", "SQLite returns this value as determined by contents of the field, not the declaration", Continue); QCOMPARE(q.value(0).type(), QVariant::String); @@ -1423,7 +1429,7 @@ void tst_QSqlDatabase::precisionPolicy() q.setNumericalPrecisionPolicy(QSql::LowPrecisionInt32); QVERIFY_SQL(q, exec(query)); QVERIFY_SQL(q, next()); - if(db.driverName().startsWith("QSQLITE")) + if (dbType == QSqlDriverPrivate::SQLite) QEXPECT_FAIL("", "SQLite returns this value as determined by contents of the field, not the declaration", Continue); QCOMPARE(q.value(0).type(), QVariant::Int); QCOMPARE(q.value(0).toInt(), 123); @@ -1431,7 +1437,7 @@ void tst_QSqlDatabase::precisionPolicy() q.setNumericalPrecisionPolicy(QSql::LowPrecisionDouble); QVERIFY_SQL(q, exec(query)); QVERIFY_SQL(q, next()); - if(db.driverName().startsWith("QSQLITE")) + if (dbType == QSqlDriverPrivate::SQLite) QEXPECT_FAIL("", "SQLite returns this value as determined by contents of the field, not the declaration", Continue); QCOMPARE(q.value(0).type(), QVariant::Double); QCOMPARE(q.value(0).toDouble(), (double)123); @@ -1439,7 +1445,7 @@ void tst_QSqlDatabase::precisionPolicy() query = QString("SELECT num FROM %1 WHERE id = 2").arg(tableName); QVERIFY_SQL(q, exec(query)); QVERIFY_SQL(q, next()); - if(db.driverName().startsWith("QSQLITE")) + if (dbType == QSqlDriverPrivate::SQLite) QEXPECT_FAIL("", "SQLite returns this value as determined by contents of the field, not the declaration", Continue); QCOMPARE(q.value(0).type(), QVariant::Double); QCOMPARE(q.value(0).toDouble(), QString("1850000000000.0001").toDouble()); @@ -1448,7 +1454,7 @@ void tst_QSqlDatabase::precisionPolicy() q.setNumericalPrecisionPolicy(QSql::HighPrecision); QVERIFY_SQL(q, exec(query)); QVERIFY_SQL(q, next()); - if(db.driverName().startsWith("QSQLITE")) + if (dbType == QSqlDriverPrivate::SQLite) QEXPECT_FAIL("", "SQLite returns this value as determined by contents of the field, not the declaration", Continue); QCOMPARE(q.value(0).type(), QVariant::String); @@ -1475,7 +1481,7 @@ void tst_QSqlDatabase::mysqlOdbc_unsignedIntegers() QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); - if (!db.driverName().startsWith("QODBC") || !dbName.toUpper().contains("MYSQL")) + if (tst_Databases::getDatabaseType(db) != QSqlDriverPrivate::MySqlServer || !db.driverName().startsWith("QODBC")) QSKIP("MySQL through ODBC-driver specific test"); QSqlQuery q(db); @@ -1659,9 +1665,6 @@ void tst_QSqlDatabase::ibase_procWithReturnValues() QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); - if (!db.driverName().startsWith("QIBASE")) - QSKIP("InterBase specific test"); - const QString procName(qTableName("qtest_proc2", __FILE__, db)); QSqlQuery q(db); @@ -1703,12 +1706,12 @@ void tst_QSqlDatabase::formatValueTrimStrings() CHECK_DATABASE(db); QSqlQuery q(db); + const QString tableName = qTableName("qtest", __FILE__, db); + QVERIFY_SQL(q, exec(QString("INSERT INTO %1 (id, t_varchar, t_char) values (50, 'Trim Test ', 'Trim Test 2 ')").arg(tableName))); + QVERIFY_SQL(q, exec(QString("INSERT INTO %1 (id, t_varchar, t_char) values (51, 'TrimTest', 'Trim Test 2')").arg(tableName))); + QVERIFY_SQL(q, exec(QString("INSERT INTO %1 (id, t_varchar, t_char) values (52, ' ', ' ')").arg(tableName))); - QVERIFY_SQL(q, exec(QString("INSERT INTO %1 (id, t_varchar, t_char) values (50, 'Trim Test ', 'Trim Test 2 ')").arg(qTableName("qtest", __FILE__, db)))); - QVERIFY_SQL(q, exec(QString("INSERT INTO %1 (id, t_varchar, t_char) values (51, 'TrimTest', 'Trim Test 2')").arg(qTableName("qtest", __FILE__, db)))); - QVERIFY_SQL(q, exec(QString("INSERT INTO %1 (id, t_varchar, t_char) values (52, ' ', ' ')").arg(qTableName("qtest", __FILE__, db)))); - - QVERIFY_SQL(q, exec(QString("SELECT t_varchar, t_char FROM %1 WHERE id >= 50 AND id <= 52 ORDER BY id").arg(qTableName("qtest", __FILE__, db)))); + QVERIFY_SQL(q, exec(QString("SELECT t_varchar, t_char FROM %1 WHERE id >= 50 AND id <= 52 ORDER BY id").arg(tableName))); QVERIFY_SQL(q, next()); @@ -1729,13 +1732,14 @@ void tst_QSqlDatabase::odbc_reopenDatabase() { QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); + const QString tableName = qTableName("qtest", __FILE__, db); CHECK_DATABASE(db); QSqlQuery q(db); - QVERIFY_SQL(q, exec("SELECT * from " + qTableName("qtest", __FILE__, db))); + QVERIFY_SQL(q, exec("SELECT * from " + tableName)); QVERIFY_SQL(q, next()); db.open(); - QVERIFY_SQL(q, exec("SELECT * from " + qTableName("qtest", __FILE__, db))); + QVERIFY_SQL(q, exec("SELECT * from " + tableName)); QVERIFY_SQL(q, next()); db.open(); } @@ -1746,14 +1750,16 @@ void tst_QSqlDatabase::odbc_bindBoolean() QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); - if (tst_Databases::isMySQL(db)) + QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); + if (dbType == QSqlDriverPrivate::MySqlServer) QSKIP("MySql has inconsistent behaviour of bit field type across versions."); QSqlQuery q(db); - QVERIFY_SQL(q, exec("CREATE TABLE " + qTableName("qtestBindBool", __FILE__, db) + "(id int, boolvalue bit)")); + const QString tableName = qTableName("qtestBindBool", __FILE__, db); + QVERIFY_SQL(q, exec("CREATE TABLE " + tableName + "(id int, boolvalue bit)")); // Bind and insert - QVERIFY_SQL(q, prepare("INSERT INTO " + qTableName("qtestBindBool", __FILE__, db) + " VALUES(?, ?)")); + QVERIFY_SQL(q, prepare("INSERT INTO " + tableName + " VALUES(?, ?)")); q.bindValue(0, 1); q.bindValue(1, true); QVERIFY_SQL(q, exec()); @@ -1762,7 +1768,7 @@ void tst_QSqlDatabase::odbc_bindBoolean() QVERIFY_SQL(q, exec()); // Retrive - QVERIFY_SQL(q, exec("SELECT id, boolvalue FROM " + qTableName("qtestBindBool", __FILE__, db) + " ORDER BY id")); + QVERIFY_SQL(q, exec("SELECT id, boolvalue FROM " + tableName + " ORDER BY id")); QVERIFY_SQL(q, next()); QCOMPARE(q.value(0).toInt(), 1); QCOMPARE(q.value(1).toBool(), true); @@ -1779,7 +1785,8 @@ void tst_QSqlDatabase::odbc_testqGetString() const QString testqGetString(qTableName("testqGetString", __FILE__, db)); QSqlQuery q(db); - if (tst_Databases::isSqlServer(db)) + QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); + if (dbType == QSqlDriverPrivate::MSSqlServer) QVERIFY_SQL(q, exec("CREATE TABLE " + testqGetString + "(id int, vcvalue varchar(MAX))")); else if(tst_Databases::isMSAccess(db)) QVERIFY_SQL(q, exec("CREATE TABLE " + testqGetString + "(id int, vcvalue memo)")); @@ -1958,7 +1965,8 @@ void tst_QSqlDatabase::odbc_uniqueidentifier() QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); - if (!tst_Databases::isSqlServer(db)) + QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); + if (dbType != QSqlDriverPrivate::MSSqlServer) QSKIP("SQL Server (ODBC) specific test"); const QString tableName(qTableName("qtest_sqlguid", __FILE__, db)); @@ -2183,7 +2191,7 @@ void tst_QSqlDatabase::mysql_savepointtest() QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); - if ( db.driverName().startsWith( "QMYSQL" ) && tst_Databases::getMySqlVersion( db ).section( QChar('.'), 0, 1 ).toDouble()<4.1 ) + if (tst_Databases::getMySqlVersion(db).section(QChar('.'), 0, 1).toDouble() < 4.1) QSKIP( "Test requires MySQL >= 4.1"); QSqlQuery q(db); diff --git a/tests/auto/sql/kernel/qsqldriver/tst_qsqldriver.cpp b/tests/auto/sql/kernel/qsqldriver/tst_qsqldriver.cpp index 3500e26f5e..53e5451e06 100644 --- a/tests/auto/sql/kernel/qsqldriver/tst_qsqldriver.cpp +++ b/tests/auto/sql/kernel/qsqldriver/tst_qsqldriver.cpp @@ -79,7 +79,8 @@ void tst_QSqlDriver::recreateTestTables(QSqlDatabase db) QSqlQuery q(db); const QString relTEST1(qTableName("relTEST1", __FILE__, db)); - if(tst_Databases::isPostgreSQL(db)) + QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); + if (dbType == QSqlDriverPrivate::PostgreSQL) QVERIFY_SQL( q, exec("set client_min_messages='warning'")); tst_Databases::safeDropTable( db, relTEST1 ); @@ -129,23 +130,24 @@ void tst_QSqlDriver::record() QSqlRecord rec = db.driver()->record(tablename); QCOMPARE(rec.count(), 4); + QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); // QTBUG-1363: QSqlField::length() always return -1 when using QODBC3 driver and QSqlDatabase::record() - if (db.driverName().startsWith("QODBC") && tst_Databases::isSqlServer(db)) + if (dbType == QSqlDriverPrivate::MSSqlServer && db.driverName().startsWith("QODBC")) QCOMPARE(rec.field(1).length(), 20); - if (db.driverName().startsWith("QIBASE")|| db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) + if (dbType == QSqlDriverPrivate::Interbase || dbType == QSqlDriverPrivate::Oracle || dbType == QSqlDriverPrivate::DB2) for(int i = 0; i < fields.count(); ++i) fields[i] = fields[i].toUpper(); for (int i = 0; i < fields.count(); ++i) QCOMPARE(rec.fieldName(i), fields[i]); - if (db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) + if (dbType == QSqlDriverPrivate::Interbase || dbType == QSqlDriverPrivate::Oracle || dbType == QSqlDriverPrivate::DB2) tablename = tablename.toUpper(); - else if (db.driverName().startsWith("QPSQL")) + else if (dbType == QSqlDriverPrivate::PostgreSQL) tablename = tablename.toLower(); - if(!db.driverName().startsWith("QODBC") && !db.databaseName().contains("PostgreSql")) { + if (dbType != QSqlDriverPrivate::PostgreSQL && !db.driverName().startsWith("QODBC")) { //check we can get records using a properly quoted table name rec = db.driver()->record(db.driver()->escapeIdentifier(tablename,QSqlDriver::TableName)); QCOMPARE(rec.count(), 4); @@ -154,18 +156,15 @@ void tst_QSqlDriver::record() for (int i = 0; i < fields.count(); ++i) QCOMPARE(rec.fieldName(i), fields[i]); - if( db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) + if (dbType == QSqlDriverPrivate::Interbase || dbType == QSqlDriverPrivate::Oracle || dbType == QSqlDriverPrivate::DB2) tablename = tablename.toLower(); - else if (db.driverName().startsWith("QPSQL")) + else if (dbType == QSqlDriverPrivate::PostgreSQL) tablename = tablename.toUpper(); //check that we can't get records using incorrect tablename casing that's been quoted rec = db.driver()->record(db.driver()->escapeIdentifier(tablename,QSqlDriver::TableName)); - if (tst_Databases::isMySQL(db) - || db.driverName().startsWith("QSQLITE") - || db.driverName().startsWith("QTDS") - || tst_Databases::isSqlServer(db) - || tst_Databases::isMSAccess(db)) + if (dbType == QSqlDriverPrivate::MySqlServer || dbType == QSqlDriverPrivate::SQLite || dbType == QSqlDriverPrivate::Sybase + || dbType == QSqlDriverPrivate::MSSqlServer || tst_Databases::isMSAccess(db)) QCOMPARE(rec.count(), 4); //mysql, sqlite and tds will match else QCOMPARE(rec.count(), 0); @@ -183,23 +182,24 @@ void tst_QSqlDriver::primaryIndex() QSqlIndex index = db.driver()->primaryIndex(tablename); QCOMPARE(index.count(), 1); - if( db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) + QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); + if (dbType == QSqlDriverPrivate::Interbase || dbType == QSqlDriverPrivate::Oracle || dbType == QSqlDriverPrivate::DB2) QCOMPARE(index.fieldName(0), QString::fromLatin1("ID")); else QCOMPARE(index.fieldName(0), QString::fromLatin1("id")); //check that we can get the primary index using a quoted tablename - if( db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) + if (dbType == QSqlDriverPrivate::Interbase || dbType == QSqlDriverPrivate::Oracle || dbType == QSqlDriverPrivate::DB2) tablename = tablename.toUpper(); - else if (db.driverName().startsWith("QPSQL")) + else if (dbType == QSqlDriverPrivate::PostgreSQL) tablename = tablename.toLower(); - if(!db.driverName().startsWith("QODBC") && !db.databaseName().contains("PostgreSql")) { + if (dbType != QSqlDriverPrivate::PostgreSQL && !db.driverName().startsWith("QODBC")) { index = db.driver()->primaryIndex(db.driver()->escapeIdentifier(tablename, QSqlDriver::TableName)); QCOMPARE(index.count(), 1); } - if( db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) + if (dbType == QSqlDriverPrivate::Interbase || dbType == QSqlDriverPrivate::Oracle || dbType == QSqlDriverPrivate::DB2) QCOMPARE(index.fieldName(0), QString::fromLatin1("ID")); else QCOMPARE(index.fieldName(0), QString::fromLatin1("id")); @@ -207,17 +207,14 @@ void tst_QSqlDriver::primaryIndex() //check that we can not get the primary index using a quoted but incorrect table name casing - if( db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) + if (dbType == QSqlDriverPrivate::Interbase || dbType == QSqlDriverPrivate::Oracle || dbType == QSqlDriverPrivate::DB2) tablename = tablename.toLower(); - else if (db.driverName().startsWith("QPSQL")) + else if (dbType == QSqlDriverPrivate::PostgreSQL) tablename = tablename.toUpper(); index = db.driver()->primaryIndex(db.driver()->escapeIdentifier(tablename, QSqlDriver::TableName)); - if (tst_Databases::isMySQL(db) - || db.driverName().startsWith("QSQLITE") - || db.driverName().startsWith("QTDS") - || tst_Databases::isSqlServer(db) - || tst_Databases::isMSAccess(db)) + if (dbType == QSqlDriverPrivate::MySqlServer || dbType == QSqlDriverPrivate::SQLite || dbType == QSqlDriverPrivate::Sybase + || dbType == QSqlDriverPrivate::MSSqlServer || tst_Databases::isMSAccess(db)) QCOMPARE(index.count(), 1); //mysql will always find the table name regardless of casing else QCOMPARE(index.count(), 0); diff --git a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp index ff458d6f2b..1a100ce706 100644 --- a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp +++ b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp @@ -97,7 +97,7 @@ private slots: void record_sqlite(); void finish_data() { generic_data(); } void finish(); - void sqlite_finish_data() { generic_data(); } + void sqlite_finish_data() { generic_data("QSQLITE"); } void sqlite_finish(); void nextResult_data() { generic_data(); } void nextResult(); @@ -107,14 +107,14 @@ private slots: void forwardOnly(); // bug specific tests - void bitField_data() {generic_data("QTDS"); } - void bitField(); - void nullBlob_data() { generic_data("QOCI"); } - void nullBlob(); + void tds_bitField_data() { generic_data("QTDS"); } + void tds_bitField(); + void oci_nullBlob_data() { generic_data("QOCI"); } + void oci_nullBlob(); void blob_data() { generic_data(); } void blob(); - void rawField_data() { generic_data("QOCI"); } - void rawField(); + void oci_rawField_data() { generic_data("QOCI"); } + void oci_rawField(); void precision_data() { generic_data(); } void precision(); void nullResult_data() { generic_data(); } @@ -131,8 +131,8 @@ private slots: void synonyms(); void oraOutValues_data() { generic_data("QOCI"); } void oraOutValues(); - void mysqlOutValues_data() { generic_data("QMYSQL"); } - void mysqlOutValues(); + void mysql_outValues_data() { generic_data("QMYSQL"); } + void mysql_outValues(); void oraClob_data() { generic_data("QOCI"); } void oraClob(); void oraLong_data() { generic_data("QOCI"); } @@ -163,8 +163,8 @@ private slots: void lastQuery(); void bindBool_data() { generic_data(); } void bindBool(); - void bindWithDoubleColonCastOperator_data() { generic_data(); } - void bindWithDoubleColonCastOperator(); + void psql_bindWithDoubleColonCastOperator_data() { generic_data("QPSQL"); } + void psql_bindWithDoubleColonCastOperator(); void queryOnInvalidDatabase_data() { generic_data(); } void queryOnInvalidDatabase(); void createQueryOnClosedDatabase_data() { generic_data(); } @@ -286,7 +286,7 @@ void tst_QSqlQuery::cleanup() QFETCH( QString, dbName ); QSqlDatabase db = QSqlDatabase::database( dbName ); CHECK_DATABASE( db ); - + const QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); if ( QTest::currentTestFunction() == QLatin1String( "numRowsAffected" ) || QTest::currentTestFunction() == QLatin1String( "transactions" ) || QTest::currentTestFunction() == QLatin1String( "size" ) @@ -295,8 +295,7 @@ void tst_QSqlQuery::cleanup() populateTestTables( db ); } - if ( QTest::currentTestFailed() && ( db.driverName().startsWith( "QOCI" ) - || db.driverName().startsWith( "QODBC" ) ) ) { + if (QTest::currentTestFailed() && (dbType == QSqlDriverPrivate::Oracle || db.driverName().startsWith("QODBC"))) { //since Oracle ODBC totally craps out on error, we init again db.close(); db.open(); @@ -315,6 +314,7 @@ void tst_QSqlQuery::generic_data(const QString& engine) void tst_QSqlQuery::dropTestTables( QSqlDatabase db ) { + QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); QStringList tablenames; // drop all the table in case a testcase failed tablenames << qtest @@ -351,24 +351,24 @@ void tst_QSqlQuery::dropTestTables( QSqlDatabase db ) << qTableName("qtest_oraOCINumber", __FILE__, db) << qTableName("bug2192", __FILE__, db); - if ( db.driverName().startsWith("QPSQL") ) + if (dbType == QSqlDriverPrivate::PostgreSQL) tablenames << qTableName("task_233829", __FILE__, db); - if ( db.driverName().startsWith("QSQLITE") ) + if (dbType == QSqlDriverPrivate::SQLite) tablenames << qTableName("record_sqlite", __FILE__, db); - if ( tst_Databases::isSqlServer( db ) || db.driverName().startsWith( "QOCI" ) ) + if (dbType == QSqlDriverPrivate::MSSqlServer || dbType == QSqlDriverPrivate::Oracle) tablenames << qTableName("qtest_longstr", __FILE__, db); - if (tst_Databases::isSqlServer( db )) + if (dbType == QSqlDriverPrivate::MSSqlServer) db.exec("DROP PROCEDURE " + qTableName("test141895_proc", __FILE__, db)); - if (tst_Databases::isMySQL( db )) - db.exec("DROP PROCEDURE IF EXISTS "+qTableName("bug6852_proc", __FILE__, db)); + if (dbType == QSqlDriverPrivate::MySqlServer) + db.exec("DROP PROCEDURE IF EXISTS "+ qTableName("bug6852_proc", __FILE__, db)); tst_Databases::safeDropTables( db, tablenames ); - if ( db.driverName().startsWith( "QOCI" ) ) { + if (dbType == QSqlDriverPrivate::Oracle) { QSqlQuery q( db ); q.exec("DROP PACKAGE " + qTableName("pkg", __FILE__, db)); } @@ -377,20 +377,20 @@ void tst_QSqlQuery::dropTestTables( QSqlDatabase db ) void tst_QSqlQuery::createTestTables( QSqlDatabase db ) { QSqlQuery q( db ); - - if ( db.driverName().startsWith( "QMYSQL" ) ) + QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); + if (dbType == QSqlDriverPrivate::MySqlServer) // ### stupid workaround until we find a way to hardcode this // in the MySQL server startup script q.exec( "set table_type=innodb" ); - else if(tst_Databases::isPostgreSQL(db)) + else if (dbType == QSqlDriverPrivate::PostgreSQL) QVERIFY_SQL( q, exec("set client_min_messages='warning'")); - if(tst_Databases::isPostgreSQL(db)) + if (dbType == QSqlDriverPrivate::PostgreSQL) QVERIFY_SQL( q, exec( "create table " + qtest + " (id serial NOT NULL, t_varchar varchar(20), t_char char(20), primary key(id)) WITH OIDS" ) ); else QVERIFY_SQL( q, exec( "create table " + qtest + " (id int "+tst_Databases::autoFieldName(db) +" NOT NULL, t_varchar varchar(20), t_char char(20), primary key(id))" ) ); - if ( tst_Databases::isSqlServer( db ) || db.driverName().startsWith( "QTDS" ) ) + if (dbType == QSqlDriverPrivate::MSSqlServer || dbType == QSqlDriverPrivate::Sybase) QVERIFY_SQL(q, exec("create table " + qTableName("qtest_null", __FILE__, db) + " (id int null, t_varchar varchar(20) null)")); else QVERIFY_SQL(q, exec("create table " + qTableName("qtest_null", __FILE__, db) + " (id int, t_varchar varchar(20))")); @@ -429,8 +429,8 @@ void tst_QSqlQuery::char1Select() QVERIFY_SQL(q, exec("insert into " + tbl + " values ('a')")); QVERIFY_SQL(q, exec("select * from " + tbl)); QVERIFY( q.next() ); - - if ( db.driverName().startsWith( "QIBASE" ) ) + QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); + if (dbType == QSqlDriverPrivate::Interbase) QCOMPARE( q.value( 0 ).toString().left( 1 ), QString( "a" ) ); else QCOMPARE( q.value( 0 ).toString(), QString( "a" ) ); @@ -444,8 +444,8 @@ void tst_QSqlQuery::char1SelectUnicode() QFETCH( QString, dbName ); QSqlDatabase db = QSqlDatabase::database( dbName ); CHECK_DATABASE( db ); - - if(db.driverName().startsWith("QDB2")) + QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); + if (dbType == QSqlDriverPrivate::DB2) QSKIP("Needs someone with more Unicode knowledge than I have to fix"); if ( db.driver()->hasFeature( QSqlDriver::Unicode ) ) { @@ -458,16 +458,14 @@ void tst_QSqlQuery::char1SelectUnicode() QString createQuery; const QString char1SelectUnicode(qTableName("char1SU", __FILE__, db)); - if ( tst_Databases::isSqlServer( db ) ) + if (dbType == QSqlDriverPrivate::MSSqlServer) createQuery = "create table " + char1SelectUnicode + "(id nchar(1))"; - else if ( db.driverName().startsWith( "QDB2" ) - || db.driverName().startsWith( "QOCI" ) - || db.driverName().startsWith( "QPSQL" ) ) + else if (dbType == QSqlDriverPrivate::DB2 || dbType == QSqlDriverPrivate::Oracle || dbType == QSqlDriverPrivate::PostgreSQL) createQuery = "create table " + char1SelectUnicode + " (id char(3))"; - else if ( db.driverName().startsWith( "QIBASE" ) ) + else if (dbType == QSqlDriverPrivate::Interbase) createQuery = "create table " + char1SelectUnicode + " (id char(1) character set unicode_fss)"; - else if ( db.driverName().startsWith( "QMYSQL" ) ) + else if (dbType == QSqlDriverPrivate::MySqlServer) createQuery = "create table " + char1SelectUnicode + " (id char(1)) " "default character set 'utf8'"; else @@ -531,18 +529,18 @@ void tst_QSqlQuery::oraRowId() QCOMPARE( q.value( 0 ).toString(), QString( "b" ) ); } -void tst_QSqlQuery::mysqlOutValues() +void tst_QSqlQuery::mysql_outValues() { QFETCH( QString, dbName ); QSqlDatabase db = QSqlDatabase::database( dbName ); CHECK_DATABASE( db ); + if (tst_Databases::getMySqlVersion(db).section(QChar('.'), 0, 0 ).toInt() < 5) + QSKIP( "Test requires MySQL >= 5.0"); + const QString hello(qTableName("hello", __FILE__, db)), qtestproc(qTableName("qtestproc", __FILE__, db)); QSqlQuery q( db ); - if ( db.driverName().startsWith( "QMYSQL" ) && tst_Databases::getMySqlVersion( db ).section( QChar('.'), 0, 0 ).toInt()<5 ) - QSKIP( "Test requires MySQL >= 5.0"); - q.exec( "drop function " + hello ); QVERIFY_SQL(q, exec("create function " + hello + " (s char(20)) returns varchar(50) READS SQL DATA return concat('Hello ', s)")); @@ -593,10 +591,11 @@ void tst_QSqlQuery::bindBool() QSqlDatabase db = QSqlDatabase::database( dbName ); CHECK_DATABASE( db ); QSqlQuery q(db); - + QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); const QString tableName(qTableName("bindBool", __FILE__, db)); + q.exec("DROP TABLE " + tableName); - QString colType = db.driverName().startsWith("QPSQL") ? QLatin1String("BOOLEAN") : QLatin1String("INT"); + QString colType = dbType == QSqlDriverPrivate::PostgreSQL ? QLatin1String("BOOLEAN") : QLatin1String("INT"); QVERIFY_SQL(q, exec("CREATE TABLE " + tableName + " (id INT, flag " + colType + " NOT NULL, PRIMARY KEY(id))")); for (int i = 0; i < 2; ++i) { @@ -849,14 +848,14 @@ void tst_QSqlQuery::outValues() QSqlQuery q( db ); q.setForwardOnly( true ); - - if ( db.driverName().startsWith( "QOCI" ) ) { + QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); + if (dbType == QSqlDriverPrivate::Oracle) { QVERIFY_SQL( q, exec( "create or replace procedure " + tst_outValues + "(x out int) is\n" "begin\n" " x := 42;\n" "end;\n" ) ); QVERIFY( q.prepare( "call " + tst_outValues + "(?)" ) ); - } else if ( db.driverName().startsWith( "QDB2" ) ) { + } else if (dbType == QSqlDriverPrivate::DB2) { q.exec( "drop procedure " + tst_outValues ); //non-fatal QVERIFY_SQL( q, exec( "CREATE PROCEDURE " + tst_outValues + " (OUT x int)\n" "LANGUAGE SQL\n" @@ -864,7 +863,7 @@ void tst_QSqlQuery::outValues() " SET x = 42;\n" "END P1" ) ); QVERIFY( q.prepare( "call " + tst_outValues + "(?)" ) ); - } else if ( tst_Databases::isSqlServer( db ) ) { + } else if (dbType == QSqlDriverPrivate::MSSqlServer) { q.exec( "drop procedure " + tst_outValues ); //non-fatal QVERIFY_SQL( q, exec( "create procedure " + tst_outValues + " (@x int out) as\n" "begin\n" @@ -938,7 +937,7 @@ void tst_QSqlQuery::value() QFETCH( QString, dbName ); QSqlDatabase db = QSqlDatabase::database( dbName ); CHECK_DATABASE( db ); - + const QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); QSqlQuery q( db ); QVERIFY_SQL( q, exec( "select id, t_varchar, t_char from " + qtest + " order by id" ) ); int i = 1; @@ -947,14 +946,14 @@ void tst_QSqlQuery::value() QCOMPARE( q.value( 0 ).toInt(), i ); QCOMPARE( q.value( "id" ).toInt(), i ); - if ( db.driverName().startsWith( "QIBASE" ) ) + if (dbType == QSqlDriverPrivate::Interbase) QVERIFY( q.value( 1 ).toString().startsWith( "VarChar" + QString::number( i ) ) ); else if ( q.value( 1 ).toString().right( 1 ) == " " ) QCOMPARE( q.value( 1 ).toString(), ( "VarChar" + QString::number( i ) + " " ) ); else QCOMPARE( q.value( 1 ).toString(), ( "VarChar" + QString::number( i ) ) ); - if ( db.driverName().startsWith( "QIBASE" ) ) + if (dbType == QSqlDriverPrivate::Interbase) QVERIFY( q.value( 2 ).toString().startsWith( "Char" + QString::number( i ) ) ); else if ( q.value( 2 ).toString().right( 1 ) != " " ) QCOMPARE( q.value( 2 ).toString(), ( "Char" + QString::number( i ) ) ); @@ -1397,24 +1396,21 @@ void tst_QSqlQuery::isNull() } /*! TDS specific BIT field test */ -void tst_QSqlQuery::bitField() +void tst_QSqlQuery::tds_bitField() { QFETCH( QString, dbName ); QSqlDatabase db = QSqlDatabase::database( dbName ); CHECK_DATABASE( db ); - - if ( !db.driverName().startsWith( "QTDS" ) ) - QSKIP( "TDS specific test"); - + const QString tableName = qTableName("qtest_bittest", __FILE__, db); QSqlQuery q( db ); - QVERIFY_SQL(q, exec("create table " + qTableName("qtest_bittest", __FILE__, db) + " (bitty bit)")); + QVERIFY_SQL(q, exec("create table " + tableName + " (bitty bit)")); - QVERIFY_SQL(q, exec("insert into " + qTableName("qtest_bittest", __FILE__, db) + " values (0)")); + QVERIFY_SQL(q, exec("insert into " + tableName + " values (0)")); - QVERIFY_SQL(q, exec("insert into " + qTableName("qtest_bittest", __FILE__, db) + " values (1)")); + QVERIFY_SQL(q, exec("insert into " + tableName + " values (1)")); - QVERIFY_SQL(q, exec("select bitty from " + qTableName("qtest_bittest", __FILE__, db))); + QVERIFY_SQL(q, exec("select bitty from " + tableName)); QVERIFY( q.next() ); @@ -1427,7 +1423,7 @@ void tst_QSqlQuery::bitField() /*! Oracle specific NULL BLOB test */ -void tst_QSqlQuery::nullBlob() +void tst_QSqlQuery::oci_nullBlob() { QFETCH( QString, dbName ); QSqlDatabase db = QSqlDatabase::database( dbName ); @@ -1457,7 +1453,7 @@ void tst_QSqlQuery::nullBlob() } /* Oracle specific RAW field test */ -void tst_QSqlQuery::rawField() +void tst_QSqlQuery::oci_rawField() { QFETCH( QString, dbName ); QSqlDatabase db = QSqlDatabase::database( dbName ); @@ -1487,13 +1483,13 @@ void tst_QSqlQuery::precision() QFETCH( QString, dbName ); QSqlDatabase db = QSqlDatabase::database( dbName ); CHECK_DATABASE( db ); - const QString qtest_precision(qTableName("qtest_precision", __FILE__, db)); + const QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); + if (dbType == QSqlDriverPrivate::Interbase) + QSKIP("DB unable to store high precision"); + const QString qtest_precision(qTableName("qtest_precision", __FILE__, db)); static const char* precStr = "1.2345678901234567891"; - if ( db.driverName().startsWith( "QIBASE" ) ) - QSKIP( "DB unable to store high precision"); - { // need a new scope for SQLITE QSqlQuery q( db ); @@ -1518,10 +1514,10 @@ void tst_QSqlQuery::precision() i++; // MySQL and TDS have crappy precisions by default - if ( db.driverName().startsWith( "QMYSQL" ) ) { + if (dbType == QSqlDriverPrivate::MySqlServer) { if ( i < 17 ) QWARN( "MySQL didn't return the right precision" ); - } else if ( db.driverName().startsWith( "QTDS" ) ) { + } else if (dbType == QSqlDriverPrivate::Sybase) { if ( i < 18 ) QWARN( "TDS didn't return the right precision" ); } else { @@ -1563,14 +1559,14 @@ void tst_QSqlQuery::transaction() QFETCH( QString, dbName ); QSqlDatabase db = QSqlDatabase::database( dbName ); CHECK_DATABASE( db ); - + const QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); if ( !db.driver()->hasFeature( QSqlDriver::Transactions ) ) QSKIP( "DBMS not transaction capable"); // this is the standard SQL QString startTransactionStr( "start transaction" ); - if ( db.driverName().startsWith( "QMYSQL" ) ) + if (dbType == QSqlDriverPrivate::MySqlServer) startTransactionStr = "begin work"; QSqlQuery q( db ); @@ -1608,7 +1604,7 @@ void tst_QSqlQuery::transaction() QCOMPARE( q.value( 0 ).toInt(), 41 ); if ( !q.exec( "rollback" ) ) { - if ( db.driverName().startsWith( "QMYSQL" ) ) { + if (dbType == QSqlDriverPrivate::MySqlServer) { qDebug( "MySQL: %s", qPrintable(tst_Databases::printError( q.lastError() ) )); QSKIP( "MySQL transaction failed "); //non-fatal } else @@ -1646,12 +1642,11 @@ void tst_QSqlQuery::joins() QFETCH( QString, dbName ); QSqlDatabase db = QSqlDatabase::database( dbName ); CHECK_DATABASE( db ); + const QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); const QString qtestj1(qTableName("qtestj1", __FILE__, db)), qtestj2(qTableName("qtestj2", __FILE__, db)); - if ( db.driverName().startsWith( "QOCI" ) - || db.driverName().startsWith( "QTDS" ) - || db.driverName().startsWith( "QODBC" ) - || db.driverName().startsWith( "QIBASE" ) ) + if (dbType == QSqlDriverPrivate::Oracle || dbType == QSqlDriverPrivate::Sybase + || dbType == QSqlDriverPrivate::Interbase || db.driverName().startsWith("QODBC")) // Oracle broken beyond recognition - cannot outer join on more than // one table. QSKIP( "DBMS cannot understand standard SQL"); @@ -1731,11 +1726,12 @@ void tst_QSqlQuery::prepare_bind_exec() QFETCH( QString, dbName ); QSqlDatabase db = QSqlDatabase::database( dbName ); CHECK_DATABASE( db ); + const QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); const QString qtest_prepare(qTableName("qtest_prepare", __FILE__, db)); - if(db.driverName().startsWith("QIBASE") && (db.databaseName() == "silence.nokia.troll.no:c:\\ibase\\testdb_ascii" || db.databaseName() == "/opt/interbase/qttest.gdb")) + if (dbType == QSqlDriverPrivate::Interbase && (db.databaseName() == "silence.nokia.troll.no:c:\\ibase\\testdb_ascii" || db.databaseName() == "/opt/interbase/qttest.gdb")) QSKIP("Can't transliterate extended unicode to ascii"); - if(db.driverName().startsWith("QDB2")) + if (dbType == QSqlDriverPrivate::DB2) QSKIP("Needs someone with more Unicode knowledge than I have to fix"); { @@ -1752,13 +1748,13 @@ void tst_QSqlQuery::prepare_bind_exec() useUnicode = false; QString createQuery; - - if(tst_Databases::isPostgreSQL(db)) + QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); + if (dbType == QSqlDriverPrivate::PostgreSQL) QVERIFY_SQL( q, exec("set client_min_messages='warning'")); - if ( tst_Databases::isSqlServer( db ) || db.driverName().startsWith( "QTDS" ) ) + if (dbType == QSqlDriverPrivate::MSSqlServer || dbType == QSqlDriverPrivate::Sybase) createQuery = "create table " + qtest_prepare + " (id int primary key, name nvarchar(200) null, name2 nvarchar(200) null)"; - else if ( tst_Databases::isMySQL(db) && useUnicode ) + else if (dbType == QSqlDriverPrivate::MySqlServer && useUnicode) createQuery = "create table " + qtest_prepare + " (id int not null primary key, name varchar(200) character set utf8, name2 varchar(200) character set utf8)"; else createQuery = "create table " + qtest_prepare + " (id int not null primary key, name varchar(200), name2 varchar(200))"; @@ -2026,7 +2022,8 @@ void tst_QSqlQuery::sqlServerLongStrings() QSqlDatabase db = QSqlDatabase::database( dbName ); CHECK_DATABASE( db ); - if ( !tst_Databases::isSqlServer( db ) ) + QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); + if (dbType != QSqlDriverPrivate::MSSqlServer) QSKIP( "SQL Server specific test"); QSqlQuery q( db ); @@ -2071,7 +2068,7 @@ void tst_QSqlQuery::invalidQuery() QFETCH( QString, dbName ); QSqlDatabase db = QSqlDatabase::database( dbName ); CHECK_DATABASE( db ); - + const QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); QSqlQuery q( db ); QVERIFY( !q.exec() ); @@ -2081,7 +2078,7 @@ void tst_QSqlQuery::invalidQuery() QVERIFY( !q.next() ); QVERIFY( !q.isActive() ); - if ( !db.driverName().startsWith( "QOCI" ) && !db.driverName().startsWith( "QDB2" ) && !db.driverName().startsWith( "QODBC" ) ) { + if (dbType != QSqlDriverPrivate::Oracle && dbType != QSqlDriverPrivate::DB2 && !db.driverName().startsWith("QODBC")) { // oracle and db2 just prepares everything without complaining if ( db.driver()->hasFeature( QSqlDriver::PreparedQueries ) ) QVERIFY( !q.prepare( "blahfasel" ) ); @@ -2343,17 +2340,12 @@ void tst_QSqlQuery::lastQuery() QCOMPARE( q.executedQuery(), sql ); } -void tst_QSqlQuery::bindWithDoubleColonCastOperator() +void tst_QSqlQuery::psql_bindWithDoubleColonCastOperator() { QFETCH( QString, dbName ); QSqlDatabase db = QSqlDatabase::database( dbName ); CHECK_DATABASE( db ); - // Only PostgreSQL support the double-colon cast operator - - if ( !db.driverName().startsWith( "QPSQL" ) ) - QSKIP( "Test requires PostgreSQL"); - const QString tablename(qTableName("bindtest", __FILE__, db)); QSqlQuery q( db ); @@ -2413,13 +2405,11 @@ void tst_QSqlQuery::createQueryOnClosedDatabase() QFETCH( QString, dbName ); QSqlDatabase db = QSqlDatabase::database( dbName ); CHECK_DATABASE( db ); - + const QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); // Only supported by these drivers - if ( !db.driverName().startsWith( "QPSQL" ) - && !db.driverName().startsWith( "QOCI" ) - && !db.driverName().startsWith( "QMYSQL" ) - && !db.driverName().startsWith( "QDB2" ) ) + if (dbType != QSqlDriverPrivate::PostgreSQL && dbType != QSqlDriverPrivate::Oracle + && dbType != QSqlDriverPrivate::MySqlServer && dbType != QSqlDriverPrivate::DB2) QSKIP( "Test is specific for PostgreSQL, Oracle, MySql and DB2"); db.close(); @@ -2505,8 +2495,6 @@ void tst_QSqlQuery::sqlite_finish() QFETCH( QString, dbName ); QSqlDatabase db = QSqlDatabase::database( dbName ); CHECK_DATABASE( db ); - if (db.driverName() != QLatin1String("QSQLITE")) - QSKIP("Sqlite3 specific test"); if ( db.databaseName().startsWith( ':' ) ) QSKIP( "This test requires a database on the filesystem, not in-memory"); @@ -2549,7 +2537,7 @@ void tst_QSqlQuery::nextResult() QFETCH( QString, dbName ); QSqlDatabase db = QSqlDatabase::database( dbName ); CHECK_DATABASE( db ); - + const QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); if ( !db.driver()->hasFeature( QSqlDriver::MultipleResultSets ) || !db.driver()->hasFeature( QSqlDriver::BatchOperations ) ) QSKIP( "DBMS does not support multiple result sets or batch operations"); @@ -2558,14 +2546,6 @@ void tst_QSqlQuery::nextResult() if ( db.driverName().startsWith( "QMYSQL" ) && tst_Databases::getMySqlVersion( db ).section( QChar('.'), 0, 0 ).toInt()<5 ) QSKIP( "Test requires MySQL >= 5.0"); - enum DriverType { ODBC, MYSQL, DB2 }; - DriverType driverType = ODBC; - - if ( db.driverName().startsWith( "QMYSQL" ) ) - driverType = MYSQL; - else if ( db.driverName().startsWith( "QDB2" ) ) - driverType = DB2; - const QString tableName(qTableName("more_results", __FILE__, db)); QVERIFY_SQL( q, exec( "CREATE TABLE " + tableName + " (id integer, text varchar(20), num numeric(6, 3), empty varchar(10));" ) ); @@ -2597,7 +2577,7 @@ void tst_QSqlQuery::nextResult() // Query that returns two result sets (batch sql) // When working with multiple result sets SQL Server insists on non-scrollable cursors - if ( driverType == ODBC ) + if (db.driverName().startsWith("QODBC")) q.setForwardOnly( true ); QVERIFY_SQL( q, exec( "SELECT id FROM " + tableName + "; SELECT text, num FROM " + tableName + ';' ) ); @@ -2618,7 +2598,7 @@ void tst_QSqlQuery::nextResult() QCOMPARE( q.record().field( 1 ).name().toUpper(), QString( "NUM" ) ); - if ( driverType == MYSQL ) + if (dbType == QSqlDriverPrivate::MySqlServer) QCOMPARE( q.record().field( 1 ).type(), QVariant::String ); else QCOMPARE( q.record().field( 1 ).type(), QVariant::Double ); @@ -2674,13 +2654,13 @@ void tst_QSqlQuery::nextResult() q.exec( QString( "DROP PROCEDURE %1;" ).arg( procName ) ); - if ( driverType == MYSQL ) + if (dbType == QSqlDriverPrivate::MySqlServer) QVERIFY_SQL( q, exec( QString( "CREATE PROCEDURE %1()" "\nBEGIN" "\nSELECT id, text FROM %2;" "\nSELECT empty, num, text, id FROM %3;" "\nEND" ).arg( procName ).arg( tableName ).arg( tableName ) ) ); - else if ( driverType == DB2 ) + else if (dbType == QSqlDriverPrivate::DB2) QVERIFY_SQL( q, exec( QString( "CREATE PROCEDURE %1()" "\nRESULT SETS 2" "\nLANGUAGE SQL" @@ -2696,7 +2676,7 @@ void tst_QSqlQuery::nextResult() "\nSELECT id, text FROM %2" "\nSELECT empty, num, text, id FROM %3" ).arg( procName ).arg( tableName ).arg( tableName ) ) ); - if ( driverType == MYSQL || driverType == DB2 ) { + if (dbType == QSqlDriverPrivate::MySqlServer || dbType == QSqlDriverPrivate::DB2) { q.setForwardOnly( true ); QVERIFY_SQL( q, exec( QString( "CALL %1()" ).arg( procName ) ) ); } else { @@ -2722,7 +2702,7 @@ void tst_QSqlQuery::nextResult() } // MySQL also counts the CALL itself as a result - if ( driverType == MYSQL ) { + if (dbType == QSqlDriverPrivate::MySqlServer) { QVERIFY( q.nextResult() ); QVERIFY( !q.isSelect() ); // ... but it's not a select QCOMPARE( q.numRowsAffected(), 0 ); // ... and no rows are affected (at least not with this procedure) @@ -2757,10 +2737,11 @@ void tst_QSqlQuery::blobsPreparedQuery() // In PostgreSQL a BLOB is not called a BLOB, but a BYTEA! :-) // ... and in SQL Server it can be called a lot, but IMAGE will do. + QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); QString typeName( "BLOB" ); - if ( db.driverName().startsWith( "QPSQL" ) ) + if (dbType == QSqlDriverPrivate::PostgreSQL) typeName = "BYTEA"; - else if ( db.driverName().startsWith( "QODBC" ) && tst_Databases::isSqlServer( db )) + else if (dbType == QSqlDriverPrivate::MSSqlServer) typeName = "IMAGE"; QVERIFY_SQL( q, exec( QString( "CREATE TABLE %1(id INTEGER, data %2)" ).arg( tableName ).arg( typeName ) ) ); @@ -2994,7 +2975,8 @@ void tst_QSqlQuery::sqlServerReturn0() QFETCH( QString, dbName ); QSqlDatabase db = QSqlDatabase::database( dbName ); CHECK_DATABASE( db ); - if (!tst_Databases::isSqlServer( db )) + QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); + if (dbType != QSqlDriverPrivate::MSSqlServer) QSKIP("SQL Server specific test"); const QString tableName(qTableName("test141895", __FILE__, db)), procName(qTableName("test141895_proc", __FILE__, db)); @@ -3088,9 +3070,9 @@ void tst_QSqlQuery::QTBUG_18435() QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); - - if (!db.driverName().startsWith("QODBC") || !tst_Databases::isSqlServer(db)) - return; + QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); + if (dbType != QSqlDriverPrivate::MSSqlServer || !db.driverName().startsWith("QODBC")) + QSKIP("SQL Server specific test"); QSqlQuery q(db); QString procName(qTableName("qtbug_18435_proc", __FILE__, db)); @@ -3120,8 +3102,6 @@ void tst_QSqlQuery::QTBUG_5251() CHECK_DATABASE( db ); const QString timetest(qTableName("timetest", __FILE__, db)); - if (!db.driverName().startsWith( "QPSQL" )) return; - QSqlQuery q(db); q.exec("DROP TABLE " + timetest); QVERIFY_SQL(q, exec("CREATE TABLE " + timetest + " (t TIME)")); @@ -3172,7 +3152,8 @@ void tst_QSqlQuery::QTBUG_6618() QFETCH( QString, dbName ); QSqlDatabase db = QSqlDatabase::database( dbName ); CHECK_DATABASE( db ); - if (!tst_Databases::isSqlServer( db )) + QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); + if (dbType != QSqlDriverPrivate::MSSqlServer) QSKIP("SQL Server specific test"); QSqlQuery q(db); @@ -3588,7 +3569,8 @@ void tst_QSqlQuery::sqlite_constraint() QSqlDatabase db = QSqlDatabase::database( dbName ); CHECK_DATABASE( db ); - if (db.driverName() != QLatin1String("QSQLITE")) + QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); + if (dbType != QSqlDriverPrivate::SQLite) QSKIP("Sqlite3 specific test"); QSqlQuery q(db); @@ -3639,9 +3621,10 @@ void tst_QSqlQuery::aggregateFunctionTypes() CHECK_DATABASE(db); QVariant::Type intType = QVariant::Int; // QPSQL uses LongLong for manipulation of integers - if (db.driverName().startsWith("QPSQL") || db.driverName().startsWith("QMYSQL")) + const QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); + if (dbType == QSqlDriverPrivate::MySqlServer || dbType == QSqlDriverPrivate::PostgreSQL) intType = QVariant::LongLong; - else if (db.driverName().startsWith("QOCI")) + else if (dbType == QSqlDriverPrivate::Oracle) intType = QVariant::Double; { const QString tableName(qTableName("numericFunctionsWithIntValues", __FILE__, db)); @@ -3653,9 +3636,9 @@ void tst_QSqlQuery::aggregateFunctionTypes() // First test without any entries QVERIFY_SQL(q, exec("SELECT SUM(id) FROM " + tableName)); QVERIFY(q.next()); - if (db.driverName().startsWith("QSQLITE")) + if (dbType == QSqlDriverPrivate::SQLite) QCOMPARE(q.record().field(0).type(), QVariant::Invalid); - else if (db.driverName().startsWith("QMYSQL")) + else if (dbType == QSqlDriverPrivate::MySqlServer) QCOMPARE(q.record().field(0).type(), QVariant::Double); else QCOMPARE(q.record().field(0).type(), intType); @@ -3666,15 +3649,15 @@ void tst_QSqlQuery::aggregateFunctionTypes() QVERIFY_SQL(q, exec("SELECT SUM(id) FROM " + tableName)); QVERIFY(q.next()); QCOMPARE(q.value(0).toInt(), 3); - if (db.driverName().startsWith("QMYSQL")) + if (dbType == QSqlDriverPrivate::MySqlServer) QCOMPARE(q.record().field(0).type(), QVariant::Double); else QCOMPARE(q.record().field(0).type(), intType); QVERIFY_SQL(q, exec("SELECT AVG(id) FROM " + tableName)); QVERIFY(q.next()); - if (db.driverName().startsWith("QSQLITE") || db.driverName().startsWith("QPSQL") - || db.driverName().startsWith("QMYSQL") || db.driverName().startsWith("QOCI")) { + if (dbType == QSqlDriverPrivate::SQLite || dbType == QSqlDriverPrivate::PostgreSQL || dbType == QSqlDriverPrivate::MySqlServer + || dbType == QSqlDriverPrivate::Oracle) { QCOMPARE(q.value(0).toDouble(), 1.5); QCOMPARE(q.record().field(0).type(), QVariant::Double); } else { @@ -3707,7 +3690,7 @@ void tst_QSqlQuery::aggregateFunctionTypes() // First test without any entries QVERIFY_SQL(q, exec("SELECT SUM(id) FROM " + tableName)); QVERIFY(q.next()); - if (db.driverName().startsWith("QSQLITE")) + if (dbType == QSqlDriverPrivate::SQLite) QCOMPARE(q.record().field(0).type(), QVariant::Invalid); else QCOMPARE(q.record().field(0).type(), QVariant::Double); @@ -3741,7 +3724,7 @@ void tst_QSqlQuery::aggregateFunctionTypes() QCOMPARE(q.record().field(0).type(), QVariant::Double); // PSQL does not have support for the round() function - if (!db.driverName().startsWith("QPSQL")) { + if (dbType != QSqlDriverPrivate::PostgreSQL) { QVERIFY_SQL(q, exec("SELECT ROUND(id, 1) FROM " + tableName + " WHERE id=1.5")); QVERIFY(q.next()); QCOMPARE(q.value(0).toDouble(), 1.5); @@ -3749,7 +3732,7 @@ void tst_QSqlQuery::aggregateFunctionTypes() QVERIFY_SQL(q, exec("SELECT ROUND(id, 0) FROM " + tableName + " WHERE id=2.5")); QVERIFY(q.next()); - if (db.driverName().startsWith("QMYSQL")) + if (dbType == QSqlDriverPrivate::MySqlServer) QCOMPARE(q.value(0).toDouble(), 2.0); else QCOMPARE(q.value(0).toDouble(), 3.0); @@ -3765,7 +3748,7 @@ void tst_QSqlQuery::aggregateFunctionTypes() QVERIFY_SQL(q, exec("SELECT MAX(txt) FROM " + tableName)); QVERIFY(q.next()); - if (db.driverName().startsWith("QSQLITE")) + if (dbType == QSqlDriverPrivate::SQLite) QCOMPARE(q.record().field(0).type(), QVariant::Invalid); else QCOMPARE(q.record().field(0).type(), QVariant::String); diff --git a/tests/auto/sql/models/qsqlquerymodel/tst_qsqlquerymodel.cpp b/tests/auto/sql/models/qsqlquerymodel/tst_qsqlquerymodel.cpp index cb9b4a5c1f..c5eafb37fb 100644 --- a/tests/auto/sql/models/qsqlquerymodel/tst_qsqlquerymodel.cpp +++ b/tests/auto/sql/models/qsqlquerymodel/tst_qsqlquerymodel.cpp @@ -158,7 +158,8 @@ void tst_QSqlQueryModel::createTestTables(QSqlDatabase db) { dropTestTables(db); QSqlQuery q(db); - if(tst_Databases::isPostgreSQL(db)) + QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); + if (dbType == QSqlDriverPrivate::PostgreSQL) QVERIFY_SQL( q, exec("set client_min_messages='warning'")); QVERIFY_SQL( q, exec("create table " + qTableName("test", __FILE__, db) + "(id integer not null, name varchar(20), title integer, primary key (id))")); QVERIFY_SQL( q, exec("create table " + qTableName("test2", __FILE__, db) + "(id integer not null, title varchar(20), primary key (id))")); @@ -312,12 +313,13 @@ void tst_QSqlQueryModel::insertColumn() QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); + const QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); DBTestModel model; model.setQuery(QSqlQuery("select * from " + qTableName("test", __FILE__, db), db)); model.fetchMore(); // necessary??? - bool isToUpper = db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2"); + bool isToUpper = (dbType == QSqlDriverPrivate::Interbase) || (dbType == QSqlDriverPrivate::Oracle) || (dbType == QSqlDriverPrivate::DB2); const QString idColumn(isToUpper ? "ID" : "id"); const QString nameColumn(isToUpper ? "NAME" : "name"); const QString titleColumn(isToUpper ? "TITLE" : "title"); @@ -415,13 +417,14 @@ void tst_QSqlQueryModel::record() QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); + const QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); QSqlQueryModel model; model.setQuery(QSqlQuery("select * from " + qTableName("test", __FILE__, db), db)); QSqlRecord rec = model.record(); - bool isToUpper = db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2"); + bool isToUpper = (dbType == QSqlDriverPrivate::Interbase) || (dbType == QSqlDriverPrivate::Oracle) || (dbType == QSqlDriverPrivate::DB2); QCOMPARE(rec.count(), 3); QCOMPARE(rec.fieldName(0), isToUpper ? QString("ID") : QString("id")); @@ -445,6 +448,7 @@ void tst_QSqlQueryModel::setHeaderData() QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); + const QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); QSqlQueryModel model; @@ -465,7 +469,7 @@ void tst_QSqlQueryModel::setHeaderData() QVERIFY(!model.setHeaderData(7, Qt::Horizontal, "foo", Qt::ToolTipRole)); QVERIFY(!model.headerData(7, Qt::Horizontal, Qt::ToolTipRole).isValid()); - bool isToUpper = db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2"); + bool isToUpper = (dbType == QSqlDriverPrivate::Interbase) || (dbType == QSqlDriverPrivate::Oracle) || (dbType == QSqlDriverPrivate::DB2); QCOMPARE(model.headerData(0, Qt::Horizontal).toString(), isToUpper ? QString("ID") : QString("id")); QCOMPARE(model.headerData(1, Qt::Horizontal).toString(), isToUpper ? QString("NAME") : QString("name")); QCOMPARE(model.headerData(2, Qt::Horizontal).toString(), QString("bar")); diff --git a/tests/auto/sql/models/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp b/tests/auto/sql/models/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp index b218a0c4f7..37c08e5101 100644 --- a/tests/auto/sql/models/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp +++ b/tests/auto/sql/models/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp @@ -151,14 +151,15 @@ void tst_QSqlRelationalTableModel::initTestCase() { foreach (const QString &dbname, dbs.dbNames) { QSqlDatabase db=QSqlDatabase::database(dbname); - if (db.driverName().startsWith("QIBASE")) + QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); + if (dbType == QSqlDriverPrivate::Interbase) { db.exec("SET DIALECT 3"); - else if (tst_Databases::isSqlServer(db)) { + } else if (dbType == QSqlDriverPrivate::MSSqlServer) { db.exec("SET ANSI_DEFAULTS ON"); db.exec("SET IMPLICIT_TRANSACTIONS OFF"); - } - else if(tst_Databases::isPostgreSQL(db)) + } else if (dbType == QSqlDriverPrivate::PostgreSQL) { db.exec("set client_min_messages='warning'"); + } recreateTestTables(db); } } @@ -245,6 +246,7 @@ void tst_QSqlRelationalTableModel::setData() QFETCH_GLOBAL(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); + const QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); // set the values using OnRowChange Strategy { @@ -327,7 +329,7 @@ void tst_QSqlRelationalTableModel::setData() //sybase doesn't allow tables with the same alias used twice as col names //so don't set up an identical relation when using the tds driver - if (!db.driverName().startsWith("QTDS")) + if (dbType != QSqlDriverPrivate::Sybase) model.setRelation(3, QSqlRelation(reltest2, "tid", "title")); model.setEditStrategy(QSqlTableModel::OnManualSubmit); @@ -340,7 +342,7 @@ void tst_QSqlRelationalTableModel::setData() QCOMPARE(model.data(model.index(2, 1)).toString(), QString("vohi2")); QCOMPARE(model.data(model.index(3, 2)).toString(), QString("herr")); - if (!db.driverName().startsWith("QTDS")) + if (dbType != QSqlDriverPrivate::Sybase) QCOMPARE(model.data(model.index(0, 3)).toString(), QString("herr")); else QCOMPARE(model.data(model.index(0, 3)).toInt(), 1); @@ -358,12 +360,12 @@ void tst_QSqlRelationalTableModel::setData() QCOMPARE(model.data(model.index(0, 3)).toInt(), 1); model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); - if (!db.driverName().startsWith("QTDS")) + if (dbType != QSqlDriverPrivate::Sybase) model.setRelation(3, QSqlRelation(reltest2, "tid", "title")); QVERIFY_SQL(model, select()); QCOMPARE(model.data(model.index(3, 2)).toString(), QString("herr")); - if (!db.driverName().startsWith("QTDS")) + if (dbType != QSqlDriverPrivate::Sybase) QCOMPARE(model.data(model.index(0, 3)).toString(), QString("herr")); else QCOMPARE(model.data(model.index(0, 3)).toInt(), 1); @@ -560,6 +562,7 @@ void tst_QSqlRelationalTableModel::insertWithStrategies() QFETCH_GLOBAL(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); + const QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); QSqlRelationalTableModel model(0, db); @@ -567,14 +570,14 @@ void tst_QSqlRelationalTableModel::insertWithStrategies() model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); model.setSort(0, Qt::AscendingOrder); - if (!db.driverName().startsWith("QTDS")) + if (dbType != QSqlDriverPrivate::Sybase) model.setRelation(3, QSqlRelation(reltest2, "tid", "title")); QVERIFY_SQL(model, select()); QCOMPARE(model.data(model.index(0,0)).toInt(), 1); QCOMPARE(model.data(model.index(0,1)).toString(), QString("harry")); QCOMPARE(model.data(model.index(0,2)).toString(), QString("herr")); - if (!db.driverName().startsWith("QTDS")) + if (dbType != QSqlDriverPrivate::Sybase) QCOMPARE(model.data(model.index(0,3)).toString(), QString("mister")); else QCOMPARE(model.data(model.index(0,3)).toInt(), 2); @@ -588,7 +591,7 @@ void tst_QSqlRelationalTableModel::insertWithStrategies() QCOMPARE(model.data(model.index(0,0)).toInt(), 1011); QCOMPARE(model.data(model.index(0,1)).toString(), QString("test")); QCOMPARE(model.data(model.index(0,2)).toString(), QString("mister")); - if (!db.driverName().startsWith("QTDS")) + if (dbType != QSqlDriverPrivate::Sybase) QCOMPARE(model.data(model.index(0,3)).toString(), QString("herr")); else QCOMPARE(model.data(model.index(0,3)).toInt(), 1); @@ -596,7 +599,7 @@ void tst_QSqlRelationalTableModel::insertWithStrategies() QCOMPARE(model.data(model.index(1,0)).toInt(), 1); QCOMPARE(model.data(model.index(1,1)).toString(), QString("harry")); QCOMPARE(model.data(model.index(1,2)).toString(), QString("herr")); - if (!db.driverName().startsWith("QTDS")) + if (dbType != QSqlDriverPrivate::Sybase) QCOMPARE(model.data(model.index(1,3)).toString(), QString("mister")); else QCOMPARE(model.data(model.index(1,3)).toInt(), 2); @@ -613,7 +616,7 @@ void tst_QSqlRelationalTableModel::insertWithStrategies() QCOMPARE(model.data(model.index(0,1)).toString(), QString("harry")); QCOMPARE(model.data(model.index(0,2)).toString(), QString("herr")); - if (!db.driverName().startsWith("QTDS")) { + if (dbType != QSqlDriverPrivate::Sybase) { QCOMPARE(model.data(model.index(0,3)).toString(), QString("mister")); model.setData(model.index(0,3),1); QCOMPARE(model.data(model.index(0,3)).toString(), QString("herr")); @@ -637,7 +640,7 @@ void tst_QSqlRelationalTableModel::insertWithStrategies() QCOMPARE(model.data(model.index(0,0)).toInt(),1012); QCOMPARE(model.data(model.index(0,1)).toString(), QString("george")); QCOMPARE(model.data(model.index(0,2)).toString(), QString("mister")); - if (!db.driverName().startsWith("QTDS")) + if (dbType != QSqlDriverPrivate::Sybase) QCOMPARE(model.data(model.index(0,3)).toString(), QString("mister")); else QCOMPARE(model.data(model.index(0,3)).toInt(), 2); @@ -646,7 +649,7 @@ void tst_QSqlRelationalTableModel::insertWithStrategies() QCOMPARE(model.data(model.index(1,0)).toInt(),1013); QCOMPARE(model.data(model.index(1,1)).toString(), QString("kramer")); QCOMPARE(model.data(model.index(1,2)).toString(), QString("mister")); - if (!db.driverName().startsWith("QTDS")) + if (dbType != QSqlDriverPrivate::Sybase) QCOMPARE(model.data(model.index(1,3)).toString(), QString("herr")); else QCOMPARE(model.data(model.index(1,3)).toInt(), 1); @@ -654,7 +657,7 @@ void tst_QSqlRelationalTableModel::insertWithStrategies() QCOMPARE(model.data(model.index(2,0)).toInt(), 1); QCOMPARE(model.data(model.index(2,1)).toString(), QString("harry")); QCOMPARE(model.data(model.index(2,2)).toString(), QString("herr")); - if (!db.driverName().startsWith("QTDS")) + if (dbType != QSqlDriverPrivate::Sybase) QCOMPARE(model.data(model.index(2,3)).toString(), QString("herr")); else QCOMPARE(model.data(model.index(2,3)).toInt(), 1); @@ -751,12 +754,13 @@ void tst_QSqlRelationalTableModel::sort() QFETCH_GLOBAL(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); + const QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); QSqlRelationalTableModel model(0, db); model.setTable(reltest1); model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); - if (!db.driverName().startsWith("QTDS")) + if (dbType != QSqlDriverPrivate::Sybase) model.setRelation(3, QSqlRelation(reltest2, "tid", "title")); model.setSort(2, Qt::DescendingOrder); @@ -772,7 +776,7 @@ void tst_QSqlRelationalTableModel::sort() model.setSort(3, Qt::AscendingOrder); QVERIFY_SQL(model, select()); - if (!db.driverName().startsWith("QTDS")) { + if (dbType != QSqlDriverPrivate::Sybase) { QCOMPARE(model.rowCount(), 4); QCOMPARE(model.data(model.index(0, 3)).toString(), QString("herr")); QCOMPARE(model.data(model.index(1, 3)).toString(), QString("mister")); @@ -801,7 +805,7 @@ void tst_QSqlRelationalTableModel::sort() model.setSort(3, Qt::AscendingOrder); QVERIFY_SQL(model, select()); - if (!db.driverName().startsWith("QTDS")) { + if (dbType != QSqlDriverPrivate::Sybase) { QCOMPARE(model.rowCount(), 6); QCOMPARE(model.data(model.index(0, 3)).toString(), QString("")); QCOMPARE(model.data(model.index(1, 3)).toString(), QString("herr")); @@ -916,13 +920,14 @@ void tst_QSqlRelationalTableModel::clearDisplayValuesCache() QFETCH_GLOBAL(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); + const QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); QSqlRelationalTableModel model(0, db); model.setTable(reltest1); model.setRelation(2, QSqlRelation(reltest2, "tid", "title")); - if (!db.driverName().startsWith("QTDS")) + if (dbType != QSqlDriverPrivate::Sybase) model.setRelation(3, QSqlRelation(reltest2, "tid", "title")); model.setSort(1, Qt::AscendingOrder); model.setEditStrategy(QSqlTableModel::OnManualSubmit); @@ -932,7 +937,7 @@ void tst_QSqlRelationalTableModel::clearDisplayValuesCache() QCOMPARE(model.data(model.index(3, 0)).toInt(), 3); QCOMPARE(model.data(model.index(3, 1)).toString(), QString("vohi")); QCOMPARE(model.data(model.index(3, 2)).toString(), QString("herr")); - if (!db.driverName().startsWith("QTDS")) + if (dbType != QSqlDriverPrivate::Sybase) QCOMPARE(model.data(model.index(3, 3)).toString(), QString("mister")); else QCOMPARE(model.data(model.index(3, 3)).toInt(), 2 ); @@ -947,7 +952,7 @@ void tst_QSqlRelationalTableModel::clearDisplayValuesCache() QCOMPARE(model.data(model.index(0, 0)).toInt(), 7); QCOMPARE(model.data(model.index(0, 1)).toString(), QString("anders")); QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr")); - if (!db.driverName().startsWith("QTDS")) + if (dbType != QSqlDriverPrivate::Sybase) QCOMPARE(model.data(model.index(0, 3)).toString(), QString("herr")); else QCOMPARE(model.data(model.index(0, 3)).toInt(), 1); @@ -955,7 +960,7 @@ void tst_QSqlRelationalTableModel::clearDisplayValuesCache() QCOMPARE(model.data(model.index(4, 0)).toInt(), 3); QCOMPARE(model.data(model.index(4, 1)).toString(), QString("vohi")); QCOMPARE(model.data(model.index(4, 2)).toString(), QString("herr")); - if (!db.driverName().startsWith("QTDS")) + if (dbType != QSqlDriverPrivate::Sybase) QCOMPARE(model.data(model.index(4, 3)).toString(), QString("mister")); else QCOMPARE(model.data(model.index(4, 3)).toInt(), 2); @@ -969,6 +974,7 @@ void tst_QSqlRelationalTableModel::insertRecordDuplicateFieldNames() QFETCH_GLOBAL(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); + const QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); QSqlRelationalTableModel model(0, db); model.setTable(reltest3); @@ -979,7 +985,7 @@ void tst_QSqlRelationalTableModel::insertRecordDuplicateFieldNames() model.setRelation(2, QSqlRelation(reltest4, "id", "name")); QVERIFY_SQL(model, select()); - if (db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) { + if (dbType == QSqlDriverPrivate::Interbase || dbType == QSqlDriverPrivate::Oracle || dbType == QSqlDriverPrivate::DB2) { QCOMPARE(model.record(1).value((reltest4+QLatin1String("_name_2")).toUpper()).toString(), QString("Trondheim")); } else { @@ -992,7 +998,7 @@ void tst_QSqlRelationalTableModel::insertRecordDuplicateFieldNames() rec.setValue(1, "Berge"); rec.setValue(2, 1); // Must insert the key value - if (db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) { + if (dbType == QSqlDriverPrivate::Interbase || dbType == QSqlDriverPrivate::Oracle || dbType == QSqlDriverPrivate::DB2) { QCOMPARE(rec.fieldName(0), QLatin1String("ID")); QCOMPARE(rec.fieldName(1), QLatin1String("NAME")); // This comes from main table } else { @@ -1001,7 +1007,7 @@ void tst_QSqlRelationalTableModel::insertRecordDuplicateFieldNames() } // The duplicate field names is aliased because it's comes from the relation's display column. - if(db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) + if (dbType == QSqlDriverPrivate::Interbase || dbType == QSqlDriverPrivate::Oracle || dbType == QSqlDriverPrivate::DB2) QCOMPARE(rec.fieldName(2), (reltest4+QLatin1String("_name_2")).toUpper()); else QCOMPARE(rec.fieldName(2), reltest4+QLatin1String("_name_2")); @@ -1090,8 +1096,9 @@ void tst_QSqlRelationalTableModel::casing() QFETCH_GLOBAL(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); + const QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); - if (db.driverName().startsWith("QSQLITE") || db.driverName().startsWith("QIBASE") || tst_Databases::isSqlServer(db)) + if (dbType == QSqlDriverPrivate::Interbase || dbType == QSqlDriverPrivate::SQLite || dbType == QSqlDriverPrivate::MSSqlServer) QSKIP("The casing test for this database is irrelevant since this database does not treat different cases as separate entities"); QSqlQuery q(db); @@ -1110,7 +1117,7 @@ void tst_QSqlRelationalTableModel::casing() QVERIFY_SQL( q, exec("insert into " + qTableName("casetest1", db) + " values(2, 'george', 2)")); QVERIFY_SQL( q, exec("insert into " + qTableName("casetest1", db) + " values(4, 'kramer', 2)")); - if (db.driverName().startsWith("QOCI")) { + if (dbType == QSqlDriverPrivate::Oracle) { //try an owner that doesn't exist QSqlRecord rec = db.driver()->record("doug." + qTableName("CASETEST1", db).toUpper()); QCOMPARE( rec.count(), 0); @@ -1156,13 +1163,15 @@ void tst_QSqlRelationalTableModel::escapedRelations() QFETCH_GLOBAL(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); + const QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); + recreateTestTables(db); QSqlRelationalTableModel model(0, db); model.setTable(reltest1); //try with relation table name quoted - if (db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) { + if (dbType == QSqlDriverPrivate::Interbase || dbType == QSqlDriverPrivate::Oracle || dbType == QSqlDriverPrivate::DB2) { model.setRelation(2, QSqlRelation(db.driver()->escapeIdentifier(reltest2.toUpper(),QSqlDriver::TableName), "tid", "title")); @@ -1187,7 +1196,7 @@ void tst_QSqlRelationalTableModel::escapedRelations() //try with index column quoted model.setJoinMode(QSqlRelationalTableModel::InnerJoin); - if (db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) { + if (dbType == QSqlDriverPrivate::Interbase || dbType == QSqlDriverPrivate::Oracle || dbType == QSqlDriverPrivate::DB2) { model.setRelation(2, QSqlRelation(reltest2, db.driver()->escapeIdentifier("tid", QSqlDriver::FieldName).toUpper(), "title")); @@ -1211,7 +1220,7 @@ void tst_QSqlRelationalTableModel::escapedRelations() //try with display column quoted model.setJoinMode(QSqlRelationalTableModel::InnerJoin); - if (db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) { + if (dbType == QSqlDriverPrivate::Interbase || dbType == QSqlDriverPrivate::Oracle || dbType == QSqlDriverPrivate::DB2) { model.setRelation(2, QSqlRelation(reltest2, "tid", @@ -1237,7 +1246,7 @@ void tst_QSqlRelationalTableModel::escapedRelations() //try with tablename and index and display columns quoted in the relation model.setJoinMode(QSqlRelationalTableModel::InnerJoin); - if (db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) { + if (dbType == QSqlDriverPrivate::Interbase || dbType == QSqlDriverPrivate::Oracle || dbType == QSqlDriverPrivate::DB2) { model.setRelation(2, QSqlRelation(reltest2, "tid", db.driver()->escapeIdentifier("title", QSqlDriver::FieldName).toUpper())); @@ -1265,12 +1274,13 @@ void tst_QSqlRelationalTableModel::escapedTableName() QFETCH_GLOBAL(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); + const QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); // set the values using OnRowChange Strategy with an escaped tablename { QSqlRelationalTableModel model(0, db); - if (db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) { + if (dbType == QSqlDriverPrivate::Interbase || dbType == QSqlDriverPrivate::Oracle || dbType == QSqlDriverPrivate::DB2) { model.setTable(db.driver()->escapeIdentifier(reltest1.toUpper(), QSqlDriver::TableName)); } else { model.setTable(db.driver()->escapeIdentifier(reltest1, QSqlDriver::TableName)); @@ -1317,7 +1327,7 @@ void tst_QSqlRelationalTableModel::escapedTableName() { QSqlRelationalTableModel model(0, db); - if (db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) { + if (dbType == QSqlDriverPrivate::Interbase || dbType == QSqlDriverPrivate::Oracle || dbType == QSqlDriverPrivate::DB2) { model.setTable(db.driver()->escapeIdentifier(reltest1.toUpper(), QSqlDriver::TableName)); } else { model.setTable(db.driver()->escapeIdentifier(reltest1, QSqlDriver::TableName)); @@ -1453,8 +1463,9 @@ void tst_QSqlRelationalTableModel::psqlSchemaTest() QFETCH_GLOBAL(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); + QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); - if(!tst_Databases::isPostgreSQL(db)) + if (dbType != QSqlDriverPrivate::PostgreSQL) QSKIP("Postgresql specific test"); QSqlRelationalTableModel model(0, db); diff --git a/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp b/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp index 771c224963..628a34f6f4 100644 --- a/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp +++ b/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp @@ -168,8 +168,9 @@ void tst_QSqlTableModel::dropTestTables() { for (int i = 0; i < dbs.dbNames.count(); ++i) { QSqlDatabase db = QSqlDatabase::database(dbs.dbNames.at(i)); + QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); QSqlQuery q(db); - if(tst_Databases::isPostgreSQL(db)) + if (dbType == QSqlDriverPrivate::PostgreSQL) QVERIFY_SQL( q, exec("set client_min_messages='warning'")); QStringList tableNames; @@ -196,6 +197,7 @@ void tst_QSqlTableModel::createTestTables() { for (int i = 0; i < dbs.dbNames.count(); ++i) { QSqlDatabase db = QSqlDatabase::database(dbs.dbNames.at(i)); + QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); QSqlQuery q(db); QVERIFY_SQL( q, exec("create table " + test + "(id int, name varchar(20), title int)")); @@ -204,7 +206,7 @@ void tst_QSqlTableModel::createTestTables() QVERIFY_SQL( q, exec("create table " + test3 + "(id int, random varchar(20), randomtwo varchar(20))")); - if(!tst_Databases::isSqlServer(db)) + if (dbType != QSqlDriverPrivate::MSSqlServer) QVERIFY_SQL(q, exec("create table " + qTableName("test4", __FILE__, db) + "(column1 varchar(50), column2 varchar(50), column3 varchar(50))")); else QVERIFY_SQL(q, exec("create table " + qTableName("test4", __FILE__, db) + "(column1 varchar(50), column2 varchar(50) NULL, column3 varchar(50))")); @@ -1705,10 +1707,11 @@ void tst_QSqlTableModel::primaryKeyOrder() QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); + QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); QSqlQuery q(db); - if(tst_Databases::isPostgreSQL(db)) + if (dbType == QSqlDriverPrivate::PostgreSQL) QVERIFY_SQL( q, exec("set client_min_messages='warning'")); QVERIFY_SQL(q, exec("create table " + qTableName("foo", __FILE__, db) + "(a varchar(20), id int not null primary key, b varchar(20))")); diff --git a/tests/benchmarks/sql/kernel/qsqlquery/main.cpp b/tests/benchmarks/sql/kernel/qsqlquery/main.cpp index 2bce545f90..4e6a444366 100644 --- a/tests/benchmarks/sql/kernel/qsqlquery/main.cpp +++ b/tests/benchmarks/sql/kernel/qsqlquery/main.cpp @@ -117,6 +117,7 @@ void tst_QSqlQuery::cleanup() QFETCH( QString, dbName ); QSqlDatabase db = QSqlDatabase::database( dbName ); CHECK_DATABASE( db ); + const QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); if ( QTest::currentTestFunction() == QLatin1String( "numRowsAffected" ) || QTest::currentTestFunction() == QLatin1String( "transactions" ) @@ -126,8 +127,7 @@ void tst_QSqlQuery::cleanup() populateTestTables( db ); } - if ( QTest::currentTestFailed() && ( db.driverName().startsWith( "QOCI" ) - || db.driverName().startsWith( "QODBC" ) ) ) { + if (QTest::currentTestFailed() && (dbType == QSqlDriverPrivate::Oracle || db.driverName().startsWith("QODBC"))) { //since Oracle ODBC totally craps out on error, we init again db.close(); db.open(); @@ -146,6 +146,7 @@ void tst_QSqlQuery::generic_data(const QString& engine) void tst_QSqlQuery::dropTestTables( QSqlDatabase db ) { + QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); QStringList tablenames; // drop all the table in case a testcase failed tablenames << qtest @@ -179,24 +180,24 @@ void tst_QSqlQuery::dropTestTables( QSqlDatabase db ) << qTableName("test141895", __FILE__, db) << qTableName("qtest_oraOCINumber", __FILE__, db); - if ( db.driverName().startsWith("QPSQL") ) + if (dbType == QSqlDriverPrivate::PostgreSQL) tablenames << qTableName("task_233829", __FILE__, db); - if ( db.driverName().startsWith("QSQLITE") ) + if (dbType == QSqlDriverPrivate::SQLite) tablenames << qTableName("record_sqlite", __FILE__, db); - if ( tst_Databases::isSqlServer( db ) || db.driverName().startsWith( "QOCI" ) ) + if (dbType == QSqlDriverPrivate::MSSqlServer || dbType == QSqlDriverPrivate::Oracle) tablenames << qTableName("qtest_longstr", __FILE__, db); - if (tst_Databases::isSqlServer( db )) + if (dbType == QSqlDriverPrivate::MSSqlServer) db.exec("DROP PROCEDURE " + qTableName("test141895_proc", __FILE__, db)); - if (tst_Databases::isMySQL( db )) + if (dbType == QSqlDriverPrivate::MySqlServer) db.exec("DROP PROCEDURE IF EXISTS "+qTableName("bug6852_proc", __FILE__, db)); tst_Databases::safeDropTables( db, tablenames ); - if ( db.driverName().startsWith( "QOCI" ) ) { + if (dbType == QSqlDriverPrivate::Oracle) { QSqlQuery q( db ); q.exec("DROP PACKAGE " + qTableName("pkg", __FILE__, db)); } @@ -204,24 +205,25 @@ void tst_QSqlQuery::dropTestTables( QSqlDatabase db ) void tst_QSqlQuery::createTestTables( QSqlDatabase db ) { + const QString qtestNull = qTableName("qtest_null", __FILE__, db); QSqlQuery q( db ); - - if ( db.driverName().startsWith( "QMYSQL" ) ) + QSqlDriverPrivate::DBMSType dbType = tst_Databases::getDatabaseType(db); + if (dbType == QSqlDriverPrivate::MySqlServer) // ### stupid workaround until we find a way to hardcode this // in the MySQL server startup script q.exec( "set table_type=innodb" ); - else if (tst_Databases::isPostgreSQL(db)) + else if (dbType == QSqlDriverPrivate::PostgreSQL) QVERIFY_SQL( q, exec("set client_min_messages='warning'")); - if (tst_Databases::isPostgreSQL(db)) + if (dbType == QSqlDriverPrivate::PostgreSQL) QVERIFY_SQL( q, exec( "create table " + qtest + " (id serial NOT NULL, t_varchar varchar(20), t_char char(20), primary key(id)) WITH OIDS" ) ); else QVERIFY_SQL( q, exec( "create table " + qtest + " (id int "+tst_Databases::autoFieldName(db) +" NOT NULL, t_varchar varchar(20), t_char char(20), primary key(id))" ) ); - if ( tst_Databases::isSqlServer( db ) || db.driverName().startsWith( "QTDS" ) ) - QVERIFY_SQL(q, exec("create table " + qTableName("qtest_null", __FILE__, db) + " (id int null, t_varchar varchar(20) null)" ) ); + if (dbType == QSqlDriverPrivate::MSSqlServer || dbType == QSqlDriverPrivate::Sybase) + QVERIFY_SQL(q, exec("create table " + qtestNull + " (id int null, t_varchar varchar(20) null)")); else - QVERIFY_SQL(q, exec("create table " + qTableName("qtest_null", __FILE__, db) + " (id int, t_varchar varchar(20))" ) ); + QVERIFY_SQL(q, exec("create table " + qtestNull + " (id int, t_varchar varchar(20))")); } void tst_QSqlQuery::populateTestTables( QSqlDatabase db ) -- cgit v1.2.3 From 4ca105b9bbf5c1e9b539da9522c630574eba3471 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Wed, 24 Apr 2013 15:41:49 +0200 Subject: Fix shortcut override for menus Since we use native Cocoa menus, we cannot rely on the normal shortcut handling. Shortcuts can be overridden by the currently focused object in Qt. In order to make that possible we need to send a QShortcutOverride event before accepting any key event. For menus the key event goes from the NSApp directly to the menu, so the shortcutOverride would not work. This is mostly an adaptation of the Qt 4 code. Task-number: QTBUG-30695 Change-Id: Icb4979309d2d6f9606eb9c8abc4130dc79926593 Reviewed-by: Gabriel de Dietrich --- src/plugins/platforms/cocoa/qcocoamenu.mm | 95 +++++++++++++++++++++++++++++++ src/plugins/platforms/cocoa/qnsview.h | 2 +- src/plugins/platforms/cocoa/qnsview.mm | 16 +++--- 3 files changed, 104 insertions(+), 9 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm index 9020aef600..59172a24c6 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.mm +++ b/src/plugins/platforms/cocoa/qcocoamenu.mm @@ -50,6 +50,27 @@ #include "qcocoawindow.h" #import "qnsview.h" +NSString *qt_mac_removePrivateUnicode(NSString* string) +{ + int len = [string length]; + if (len) { + QVarLengthArray characters(len); + bool changed = false; + for (int i = 0; iisEnabled(); } +- (BOOL)menuHasKeyEquivalent:(NSMenu *)menu forEvent:(NSEvent *)event target:(id *)target action:(SEL *)action +{ + /* + Check if the menu actually has a keysequence defined for this key event. + If it does, then we will first send the key sequence to the QWidget that has focus + since (in Qt's eyes) it needs to a chance at the key event first (QEvent::ShortcutOverride). + If the widget accepts the key event, we then return YES, but set the target and action to be nil, + which means that the action should not be triggered, and instead dispatch the event ourselves. + In every other case we return NO, which means that Cocoa can do as it pleases + (i.e., fire the menu action). + */ + + // Change the private unicode keys to the ones used in setting the "Key Equivalents" + NSString *characters = qt_mac_removePrivateUnicode([event characters]); + if ([self hasShortcut:menu + forKey:characters + // Interested only in Shift, Cmd, Ctrl & Alt Keys, so ignoring masks like, Caps lock, Num Lock ... + forModifiers:([event modifierFlags] & (NSShiftKeyMask | NSControlKeyMask | NSCommandKeyMask | NSAlternateKeyMask)) + ]) { + QObject *object = qApp->focusObject(); + if (object) { + QChar ch; + int keyCode; + ulong nativeModifiers = [event modifierFlags]; + Qt::KeyboardModifiers modifiers = [QNSView convertKeyModifiers: nativeModifiers]; + NSString *charactersIgnoringModifiers = [event charactersIgnoringModifiers]; + NSString *characters = [event characters]; + + if ([charactersIgnoringModifiers length] > 0) { // convert the first character into a key code + if ((modifiers & Qt::ControlModifier) && ([characters length] != 0)) { + ch = QChar([characters characterAtIndex:0]); + } else { + ch = QChar([charactersIgnoringModifiers characterAtIndex:0]); + } + keyCode = qt_mac_cocoaKey2QtKey(ch); + } else { + // might be a dead key + ch = QChar::ReplacementCharacter; + keyCode = Qt::Key_unknown; + } + + QKeyEvent accel_ev(QEvent::ShortcutOverride, (keyCode & (~Qt::KeyboardModifierMask)), + Qt::KeyboardModifiers(keyCode & Qt::KeyboardModifierMask)); + accel_ev.ignore(); + QCoreApplication::sendEvent(object, &accel_ev); + if (accel_ev.isAccepted()) { + [[NSApp keyWindow] sendEvent: event]; + *target = nil; + *action = nil; + return YES; + } + } + } + return NO; +} + +- (BOOL)hasShortcut:(NSMenu *)menu forKey:(NSString *)key forModifiers:(NSUInteger)modifier +{ + for (NSMenuItem *item in [menu itemArray]) { + if (![item isEnabled] || [item isHidden] || [item isSeparatorItem]) + continue; + if ([item hasSubmenu] + && [self hasShortcut:[item submenu] forKey:key forModifiers:modifier]) + return YES; + + NSString *menuKey = [item keyEquivalent]; + if (menuKey + && NSOrderedSame == [menuKey compare:key] + && modifier == [item keyEquivalentModifierMask]) + return YES; + } + return NO; +} + @end QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h index 68145ec914..67b16b4b32 100644 --- a/src/plugins/platforms/cocoa/qnsview.h +++ b/src/plugins/platforms/cocoa/qnsview.h @@ -107,7 +107,7 @@ QT_END_NAMESPACE - (void)handleFrameStrutMouseEvent:(NSEvent *)theEvent; - (int) convertKeyCode : (QChar)keyCode; -- (Qt::KeyboardModifiers) convertKeyModifiers : (ulong)modifierFlags; ++ (Qt::KeyboardModifiers) convertKeyModifiers : (ulong)modifierFlags; - (void)handleKeyEvent:(NSEvent *)theEvent eventType:(int)eventType; - (void)keyDown:(NSEvent *)theEvent; - (void)keyUp:(NSEvent *)theEvent; diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 52e2d781ee..d1dd939600 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -494,7 +494,7 @@ static QTouchDevice *touchDevice = 0; QCocoaDrag* nativeDrag = static_cast(QGuiApplicationPrivate::platformIntegration()->drag()); nativeDrag->setLastMouseEvent(theEvent, self); - Qt::KeyboardModifiers keyboardModifiers = [self convertKeyModifiers:[theEvent modifierFlags]]; + Qt::KeyboardModifiers keyboardModifiers = [QNSView convertKeyModifiers:[theEvent modifierFlags]]; QWindowSystemInterface::handleMouseEvent(m_window, timestamp, qtWindowPoint, qtScreenPoint, m_buttons, keyboardModifiers); } @@ -556,7 +556,7 @@ static QTouchDevice *touchDevice = 0; [inputManager handleMouseEvent:theEvent]; } } else { - if ([self convertKeyModifiers:[theEvent modifierFlags]] & Qt::MetaModifier) { + if ([QNSView convertKeyModifiers:[theEvent modifierFlags]] & Qt::MetaModifier) { m_buttons |= Qt::RightButton; m_sendUpAsRightButton = true; } else { @@ -826,7 +826,7 @@ static QTouchDevice *touchDevice = 0; if ([theEvent respondsToSelector:@selector(scrollingDeltaX)]) { NSEventPhase phase = [theEvent phase]; if (phase == NSEventPhaseBegan) { - currentWheelModifiers = [self convertKeyModifiers:[theEvent modifierFlags]]; + currentWheelModifiers = [QNSView convertKeyModifiers:[theEvent modifierFlags]]; } QWindowSystemInterface::handleWheelEvent(m_window, qt_timestamp, qt_windowPoint, qt_screenPoint, pixelDelta, angleDelta, currentWheelModifiers); @@ -838,7 +838,7 @@ static QTouchDevice *touchDevice = 0; #endif { QWindowSystemInterface::handleWheelEvent(m_window, qt_timestamp, qt_windowPoint, qt_screenPoint, pixelDelta, angleDelta, - [self convertKeyModifiers:[theEvent modifierFlags]]); + [QNSView convertKeyModifiers:[theEvent modifierFlags]]); } } #endif //QT_NO_WHEELEVENT @@ -848,7 +848,7 @@ static QTouchDevice *touchDevice = 0; return qt_mac_cocoaKey2QtKey(keyChar); } -- (Qt::KeyboardModifiers) convertKeyModifiers : (ulong)modifierFlags ++ (Qt::KeyboardModifiers) convertKeyModifiers : (ulong)modifierFlags { Qt::KeyboardModifiers qtMods =Qt::NoModifier; if (modifierFlags & NSShiftKeyMask) @@ -868,7 +868,7 @@ static QTouchDevice *touchDevice = 0; { ulong timestamp = [nsevent timestamp] * 1000; ulong nativeModifiers = [nsevent modifierFlags]; - Qt::KeyboardModifiers modifiers = [self convertKeyModifiers: nativeModifiers]; + Qt::KeyboardModifiers modifiers = [QNSView convertKeyModifiers: nativeModifiers]; NSString *charactersIgnoringModifiers = [nsevent charactersIgnoringModifiers]; NSString *characters = [nsevent characters]; @@ -948,7 +948,7 @@ static QTouchDevice *touchDevice = 0; { ulong timestamp = [nsevent timestamp] * 1000; ulong modifiers = [nsevent modifierFlags]; - Qt::KeyboardModifiers qmodifiers = [self convertKeyModifiers:modifiers]; + Qt::KeyboardModifiers qmodifiers = [QNSView convertKeyModifiers:modifiers]; // calculate the delta and remember the current modifiers for next time static ulong m_lastKnownModifiers; @@ -1278,7 +1278,7 @@ static QTouchDevice *touchDevice = 0; Qt::DropActions qtAllowed = qt_mac_mapNSDragOperations([sender draggingSourceOperationMask]); // update these so selecting move/copy/link works - QGuiApplicationPrivate::modifier_buttons = [self convertKeyModifiers: [[NSApp currentEvent] modifierFlags]]; + QGuiApplicationPrivate::modifier_buttons = [QNSView convertKeyModifiers: [[NSApp currentEvent] modifierFlags]]; QPlatformDragQtResponse response(false, Qt::IgnoreAction, QRect()); if ([sender draggingSource] != nil) { -- cgit v1.2.3 From 2e69015d74a903d7319dec164214b9f443980a08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Fri, 26 Apr 2013 09:32:01 +0200 Subject: Increase the loopLevel when activating menu items. Apply 0293aff5c44202e5c62e229b74d8bd0bf9206185 from Qt 4. Without this, calls to deleteLater() may create delete later events with a loopLevel of 1. Those events will not be processed until QApplication::exec() returns. Add a QScopedLoopLevelCounter that increases the loopLevel for the duration of the activated() call. Task-number: QTBUG-30660 Change-Id: I7ab3bb3a53243691b8f7f64e025150e5cc7da2c8 Reviewed-by: Gabriel de Dietrich --- src/plugins/platforms/cocoa/qcocoamenu.mm | 3 +++ src/plugins/platforms/cocoa/qcocoamenuloader.mm | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm index 59172a24c6..565c77fd44 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.mm +++ b/src/plugins/platforms/cocoa/qcocoamenu.mm @@ -45,6 +45,8 @@ #include "qcocoaautoreleasepool.h" #include +#include +#include #include "qcocoaapplication.h" #include "qcocoamenuloader.h" #include "qcocoawindow.h" @@ -110,6 +112,7 @@ static inline QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *getMenuLoader() - (void) itemFired:(NSMenuItem*) item { QCocoaMenuItem *cocoaItem = reinterpret_cast([item tag]); + QScopedLoopLevelCounter loopLevelCounter(QGuiApplicationPrivate::instance()->threadData); cocoaItem->activated(); } diff --git a/src/plugins/platforms/cocoa/qcocoamenuloader.mm b/src/plugins/platforms/cocoa/qcocoamenuloader.mm index 4fb7969ff4..62b722d2d2 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuloader.mm +++ b/src/plugins/platforms/cocoa/qcocoamenuloader.mm @@ -47,10 +47,12 @@ #include "qcocoamenuitem.h" #include +#include #include #include #include #include +#include QT_FORWARD_DECLARE_CLASS(QCFString) QT_FORWARD_DECLARE_CLASS(QString) @@ -305,6 +307,7 @@ QT_END_NAMESPACE if ([item tag]) { QCocoaMenuItem *cocoaItem = reinterpret_cast([item tag]); + QScopedLoopLevelCounter loopLevelCounter(QGuiApplicationPrivate::instance()->threadData); cocoaItem->activated(); } } -- cgit v1.2.3 From 9f1b64766b64fac2df8dd112d2801c15a781bdf9 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Wed, 24 Apr 2013 10:59:45 +0200 Subject: Don't use the SubWindow flag for windows embedded in foreign windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead, add QCocoaWindow::setEmbeddedInForeignView which can be called via QPlatformNativeInterface::NativeResourceForIntegrationFunction Task-number: QTBUG-30805 Change-Id: I05861e80ca664ddb430216388cf0fec573a4d32b Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoanativeinterface.h | 3 +++ src/plugins/platforms/cocoa/qcocoanativeinterface.mm | 8 ++++++++ src/plugins/platforms/cocoa/qcocoawindow.h | 7 ++++++- src/plugins/platforms/cocoa/qcocoawindow.mm | 11 +++++++++-- src/plugins/platforms/cocoa/qnsview.mm | 8 ++++---- 5 files changed, 30 insertions(+), 7 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.h b/src/plugins/platforms/cocoa/qcocoanativeinterface.h index c344ebc42c..2e5e65f577 100644 --- a/src/plugins/platforms/cocoa/qcocoanativeinterface.h +++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.h @@ -115,6 +115,9 @@ private: // Embedding NSViews as child QWindows static void setWindowContentView(QPlatformWindow *window, void *nsViewContentView); + // Set a QWindow as a "guest" (subwindow) of a non-QWindow + static void setEmbeddedInForeignView(QPlatformWindow *window, bool embedded); + // Register if a window should deliver touch events. Enabling // touch events has implications for delivery of other events, // for example by causing scrolling event lag. diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm index 64e2b619c1..873fa3eed9 100644 --- a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm +++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm @@ -120,6 +120,8 @@ QPlatformNativeInterface::NativeResourceForIntegrationFunction QCocoaNativeInter return NativeResourceForIntegrationFunction(QCocoaNativeInterface::setWindowContentView); if (resource.toLower() == "registertouchwindow") return NativeResourceForIntegrationFunction(QCocoaNativeInterface::registerTouchWindow); + if (resource.toLower() == "setembeddedinforeignview") + return NativeResourceForIntegrationFunction(QCocoaNativeInterface::setEmbeddedInForeignView); return 0; } @@ -229,6 +231,12 @@ void QCocoaNativeInterface::setWindowContentView(QPlatformWindow *window, void * cocoaPlatformWindow->setContentView(reinterpret_cast(contentView)); } +void QCocoaNativeInterface::setEmbeddedInForeignView(QPlatformWindow *window, bool embedded) +{ + QCocoaWindow *cocoaPlatformWindow = static_cast(window); + cocoaPlatformWindow->setEmbeddedInForeignView(embedded); +} + void QCocoaNativeInterface::registerTouchWindow(QWindow *window, bool enable) { if (!window) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h index ff7f99f96a..b2657b7725 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.h +++ b/src/plugins/platforms/cocoa/qcocoawindow.h @@ -127,6 +127,8 @@ public: NSView *contentView() const; void setContentView(NSView *contentView); + void setEmbeddedInForeignView(bool subwindow); + void windowWillMove(); void windowDidMove(); void windowDidResize(); @@ -175,7 +177,10 @@ public: // for QNSView NSView *m_contentView; QNSView *m_qtView; NSWindow *m_nsWindow; - bool m_contentViewIsEmbedded; // true if the m_contentView is embedded in a "foregin" NSView hiearchy + + // TODO merge to one variable if possible + bool m_contentViewIsEmbedded; // true if the m_contentView is actually embedded in a "foreign" NSView hiearchy + bool m_contentViewIsToBeEmbedded; // true if the m_contentView is intended to be embedded in a "foreign" NSView hiearchy QNSWindowDelegate *m_nsWindowDelegate; Qt::WindowFlags m_windowFlags; diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 5cfcec8e54..14b9b66c92 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -194,6 +194,7 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw) : QPlatformWindow(tlw) , m_nsWindow(0) , m_contentViewIsEmbedded(false) + , m_contentViewIsToBeEmbedded(false) , m_nsWindowDelegate(0) , m_synchedWindowState(Qt::WindowActive) , m_windowModality(Qt::NonModal) @@ -654,6 +655,12 @@ void QCocoaWindow::setContentView(NSView *contentView) recreateWindow(parent()); // Adds the content view to parent NSView } +void QCocoaWindow::setEmbeddedInForeignView(bool embedded) +{ + m_contentViewIsToBeEmbedded = embedded; + recreateWindow(0); // destroy what was already created +} + void QCocoaWindow::windowWillMove() { // Close any open popups on window move @@ -715,8 +722,8 @@ void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow) m_nsWindowDelegate = 0; } - if (window()->type() == Qt::SubWindow) { - // Subwindows don't have a NSWindow. + if (m_contentViewIsToBeEmbedded) { + // An embedded window doesn't have its own NSWindow. } else if (!parentWindow) { // Create a new NSWindow if this is a top-level window. m_nsWindow = createNSWindow(); diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index d1dd939600..a53d6c4e44 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -172,7 +172,7 @@ static QTouchDevice *touchDevice = 0; - (void)viewDidMoveToSuperview { - if (!(m_window->type() & Qt::SubWindow)) + if (!(m_platformWindow->m_contentViewIsToBeEmbedded)) return; if ([self superview]) { @@ -208,7 +208,7 @@ static QTouchDevice *touchDevice = 0; NSRect rect = [self frame]; NSRect windowRect = [[self window] frame]; geometry = QRect(windowRect.origin.x, qt_mac_flipYCoordinate(windowRect.origin.y + rect.size.height), rect.size.width, rect.size.height); - } else if (m_window->type() & Qt::SubWindow) { + } else if (m_platformWindow->m_contentViewIsToBeEmbedded) { // embedded child window, use the frame rect ### merge with case below geometry = qt_mac_toQRect([self bounds]); } else { @@ -229,9 +229,9 @@ static QTouchDevice *touchDevice = 0; m_platformWindow->QPlatformWindow::setGeometry(geometry); // Don't send the geometry change if the QWindow is designated to be - // embedded in a foregin view hiearchy but has not actually been + // embedded in a foreign view hiearchy but has not actually been // embedded yet - it's too early. - if ((m_window->type() & Qt::SubWindow) && !m_platformWindow->m_contentViewIsEmbedded) + if (m_platformWindow->m_contentViewIsToBeEmbedded && !m_platformWindow->m_contentViewIsEmbedded) return; // Send a geometry change event to Qt, if it's ready to handle events -- cgit v1.2.3 From e7c3b21b7c1ed9247cb2f9eeddc154534a038549 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 25 Apr 2013 16:44:30 +0200 Subject: make sure qmake finds itself in CWD on windows and consequently that it finds qt.conf. Task-number: QTBUG-30583 Change-Id: I48441477e941d9609270d6e5e1b405127c0c0aca Reviewed-by: Joerg Bornemann --- qmake/option.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/qmake/option.cpp b/qmake/option.cpp index 983d3490d8..4f7cdb34a2 100644 --- a/qmake/option.cpp +++ b/qmake/option.cpp @@ -338,6 +338,7 @@ Option::init(int argc, char **argv) QDir currentDir = QDir::current(); #ifdef Q_OS_WIN QStringList paths = QString::fromLocal8Bit(pEnv).split(QLatin1String(";")); + paths.prepend(QLatin1String(".")); #else QStringList paths = QString::fromLocal8Bit(pEnv).split(QLatin1String(":")); #endif -- cgit v1.2.3 From e80a8fe8613a4275187d776e08f28a5395652c56 Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Thu, 25 Apr 2013 12:24:28 +0200 Subject: qdoc: Adjust regexp that generates tags from module names Use a slightly better regular expression for splitting module names into tags used for example manifest files. This will correctly split words with consecutive capital letters (e.g. QtDBus) Change-Id: I1320e08a1fbd44f718b82a1fcfea19eabca035fc Reviewed-by: Martin Smith --- src/tools/qdoc/htmlgenerator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/qdoc/htmlgenerator.cpp b/src/tools/qdoc/htmlgenerator.cpp index c5dc7d17c9..d5e079d910 100644 --- a/src/tools/qdoc/htmlgenerator.cpp +++ b/src/tools/qdoc/htmlgenerator.cpp @@ -4184,7 +4184,7 @@ void HtmlGenerator::generateManifestFile(QString manifest, QString element) writer.writeEndElement(); // description // Add words from module name as tags (QtQuickControls -> qt,quick,controls) - QRegExp re("([A-Z][a-z0-9]+)"); + QRegExp re("([A-Z]+[a-z0-9]*)"); int pos = 0; while ((pos = re.indexIn(project, pos)) != -1) { tags << re.cap(1).toLower(); -- cgit v1.2.3 From e12d384d7b898f949bc5ad27a473eee2ec92a711 Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Fri, 19 Apr 2013 13:35:30 +0200 Subject: Doc: Fix module name in .qdocconf Use CamelCase for module name(s) used in in .qdocconf - this is required as qdoc will generate visible output (tags in example manifest files) based on these names. Change-Id: Ie246e740203ee0b996fea5dee612bf7f61638991 Reviewed-by: Jerome Pasion --- src/dbus/doc/qtdbus.qdocconf | 22 +++++++++++----------- src/opengl/doc/qtopengl.qdocconf | 22 +++++++++++----------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/dbus/doc/qtdbus.qdocconf b/src/dbus/doc/qtdbus.qdocconf index f3b4c0f1d7..b47e02ff43 100644 --- a/src/dbus/doc/qtdbus.qdocconf +++ b/src/dbus/doc/qtdbus.qdocconf @@ -1,7 +1,7 @@ include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf) # Name of the project which must match the outputdir. Determines the .index file -project = qtdbus +project = QtDBus # Directories in which to search for files to document and images. # By default set to the root directory of the project for sources @@ -29,23 +29,23 @@ depends += qtcore # Defines the name of the project. You cannot use operators (+, =, -) in # the name. Properties for this project are set using a qhp..property # format. -qhp.projects = qtdbus +qhp.projects = QtDBus # Sets the name of the output qhp file. -qhp.qtdbus.file = qtdbus.qhp +qhp.QtDBus.file = qtdbus.qhp # Namespace for the output file. This namespace is used to distinguish between # different documentation files in Creator/Assistant. -qhp.qtdbus.namespace = org.qt-project.qtdbus.$QT_VERSION_TAG +qhp.QtDBus.namespace = org.qt-project.qtdbus.$QT_VERSION_TAG # Title for the package, will be the main title for the package in # Assistant/Creator. -qhp.qtdbus.indexTitle = Qt D-Bus +qhp.QtDBus.indexTitle = Qt D-Bus # Only update the name of the project for the next variables. -qhp.qtdbus.virtualFolder = qtdbus -qhp.qtdbus.subprojects = classes -qhp.qtdbus.subprojects.classes.title = C++ Classes -qhp.qtdbus.subprojects.classes.indexTitle = Qt D-Bus C++ Classes -qhp.qtdbus.subprojects.classes.selectors = class fake:headerfile -qhp.qtdbus.subprojects.classes.sortPages = true +qhp.QtDBus.virtualFolder = qtdbus +qhp.QtDBus.subprojects = classes +qhp.QtDBus.subprojects.classes.title = C++ Classes +qhp.QtDBus.subprojects.classes.indexTitle = Qt D-Bus C++ Classes +qhp.QtDBus.subprojects.classes.selectors = class fake:headerfile +qhp.QtDBus.subprojects.classes.sortPages = true diff --git a/src/opengl/doc/qtopengl.qdocconf b/src/opengl/doc/qtopengl.qdocconf index d0f49fd602..eea618d8ea 100644 --- a/src/opengl/doc/qtopengl.qdocconf +++ b/src/opengl/doc/qtopengl.qdocconf @@ -1,7 +1,7 @@ include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf) # Name of the project which must match the outputdir. Determines the .index file -project = qtopengl +project = QtOpenGL # Directories in which to search for files to document and images. # By default set to the root directory of the project for sources @@ -32,23 +32,23 @@ examplesinstallpath = opengl # Defines the name of the project. You cannot use operators (+, =, -) in # the name. Properties for this project are set using a qhp..property # format. -qhp.projects = qtopengl +qhp.projects = QtOpenGL # Sets the name of the output qhp file. -qhp.qtopengl.file = qtopengl.qhp +qhp.QtOpenGL.file = qtopengl.qhp # Namespace for the output file. This namespace is used to distinguish between # different documentation files in Creator/Assistant. -qhp.qtopengl.namespace = org.qt-project.qtopengl.$QT_VERSION_TAG +qhp.QtOpenGL.namespace = org.qt-project.qtopengl.$QT_VERSION_TAG # Title for the package, will be the main title for the package in # Assistant/Creator. -qhp.qtopengl.indexTitle = Qt OpenGL +qhp.QtOpenGL.indexTitle = Qt OpenGL # Only update the name of the project for the next variables. -qhp.qtopengl.virtualFolder = qtopengl -qhp.qtopengl.subprojects = classes -qhp.qtopengl.subprojects.classes.title = C++ Classes -qhp.qtopengl.subprojects.classes.indexTitle = Qt OpenGL C++ Classes -qhp.qtopengl.subprojects.classes.selectors = class fake:headerfile -qhp.qtopengl.subprojects.classes.sortPages = true +qhp.QtOpenGL.virtualFolder = qtopengl +qhp.QtOpenGL.subprojects = classes +qhp.QtOpenGL.subprojects.classes.title = C++ Classes +qhp.QtOpenGL.subprojects.classes.indexTitle = Qt OpenGL C++ Classes +qhp.QtOpenGL.subprojects.classes.selectors = class fake:headerfile +qhp.QtOpenGL.subprojects.classes.sortPages = true -- cgit v1.2.3 From c90d9b697f6ef549d33047332a9c44b40ded63f5 Mon Sep 17 00:00:00 2001 From: Josh Faust Date: Thu, 14 Mar 2013 15:13:34 -0700 Subject: Fix ignoring close events on OSX MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QNSWindowDelegate was not handling windowShouldClose, which is how you can tell Cocoa that your window should not close if the close button is pressed. This change moves the close handling from windowWillClose to windowShouldClose, and adds an optional "accepted" pointer to QWindowSystemInterface::handleCloseEvent so that QNSWindowDelegate can return a true/false value for whether the window should actually close Task-number: QTBUG-28965 Change-Id: I67c6296ad42cbeeb71413e05411467d4e558adb4 Reviewed-by: Morten Johan Sørvig --- src/gui/kernel/qguiapplication.cpp | 3 +++ src/gui/kernel/qwindowsysteminterface.cpp | 4 ++-- src/gui/kernel/qwindowsysteminterface.h | 2 +- src/gui/kernel/qwindowsysteminterface_p.h | 6 ++++-- src/plugins/platforms/cocoa/qcocoawindow.h | 2 +- src/plugins/platforms/cocoa/qcocoawindow.mm | 6 ++++-- src/plugins/platforms/cocoa/qnswindowdelegate.h | 1 + src/plugins/platforms/cocoa/qnswindowdelegate.mm | 6 ++++-- 8 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 585eca84ca..3c79e62e75 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -1740,6 +1740,9 @@ void QGuiApplicationPrivate::processCloseEvent(QWindowSystemInterfacePrivate::Cl QCloseEvent event; QGuiApplication::sendSpontaneousEvent(e->window.data(), &event); + if (e->accepted) { + *(e->accepted) = !event.isAccepted(); + } } void QGuiApplicationPrivate::processFileOpenEvent(QWindowSystemInterfacePrivate::FileOpenEvent *e) diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp index d2add91d66..7dc1e7f7e5 100644 --- a/src/gui/kernel/qwindowsysteminterface.cpp +++ b/src/gui/kernel/qwindowsysteminterface.cpp @@ -140,11 +140,11 @@ void QWindowSystemInterface::handleGeometryChange(QWindow *tlw, const QRect &new QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); } -void QWindowSystemInterface::handleCloseEvent(QWindow *tlw) +void QWindowSystemInterface::handleCloseEvent(QWindow *tlw, bool *accepted) { if (tlw) { QWindowSystemInterfacePrivate::CloseEvent *e = - new QWindowSystemInterfacePrivate::CloseEvent(tlw); + new QWindowSystemInterfacePrivate::CloseEvent(tlw, accepted); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); } } diff --git a/src/gui/kernel/qwindowsysteminterface.h b/src/gui/kernel/qwindowsysteminterface.h index 212259c113..521c2a4941 100644 --- a/src/gui/kernel/qwindowsysteminterface.h +++ b/src/gui/kernel/qwindowsysteminterface.h @@ -131,7 +131,7 @@ public: static void handleTouchCancelEvent(QWindow *w, ulong timestamp, QTouchDevice *device, Qt::KeyboardModifiers mods = Qt::NoModifier); static void handleGeometryChange(QWindow *w, const QRect &newRect); - static void handleCloseEvent(QWindow *w); + static void handleCloseEvent(QWindow *w, bool *accepted = 0); static void handleEnterEvent(QWindow *w, const QPointF &local = QPointF(), const QPointF& global = QPointF()); static void handleLeaveEvent(QWindow *w); static void handleEnterLeaveEvent(QWindow *enter, QWindow *leave, const QPointF &local = QPointF(), const QPointF& global = QPointF()); diff --git a/src/gui/kernel/qwindowsysteminterface_p.h b/src/gui/kernel/qwindowsysteminterface_p.h index f1bc4667f7..a6ea15c5f2 100644 --- a/src/gui/kernel/qwindowsysteminterface_p.h +++ b/src/gui/kernel/qwindowsysteminterface_p.h @@ -105,9 +105,11 @@ public: class CloseEvent : public WindowSystemEvent { public: - explicit CloseEvent(QWindow *w) - : WindowSystemEvent(Close), window(w) { } + explicit CloseEvent(QWindow *w, bool *a = 0) + : WindowSystemEvent(Close), window(w), accepted(a) + { } QPointer window; + bool *accepted; }; class GeometryChangeEvent : public WindowSystemEvent { diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h index b2657b7725..60f448044e 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.h +++ b/src/plugins/platforms/cocoa/qcocoawindow.h @@ -132,7 +132,7 @@ public: void windowWillMove(); void windowDidMove(); void windowDidResize(); - void windowWillClose(); + bool windowShouldClose(); bool windowIsPopupType(Qt::WindowType type = Qt::Widget) const; NSInteger windowLevel(Qt::WindowFlags flags); diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 14b9b66c92..8e9fcc443b 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -684,10 +684,12 @@ void QCocoaWindow::windowDidResize() [m_qtView updateGeometry]; } -void QCocoaWindow::windowWillClose() +bool QCocoaWindow::windowShouldClose() { - QWindowSystemInterface::handleCloseEvent(window()); + bool accepted = false; + QWindowSystemInterface::handleCloseEvent(window(), &accepted); QWindowSystemInterface::flushWindowSystemEvents(); + return accepted; } bool QCocoaWindow::windowIsPopupType(Qt::WindowType type) const diff --git a/src/plugins/platforms/cocoa/qnswindowdelegate.h b/src/plugins/platforms/cocoa/qnswindowdelegate.h index 98ad7b8c9d..a5b46a971f 100644 --- a/src/plugins/platforms/cocoa/qnswindowdelegate.h +++ b/src/plugins/platforms/cocoa/qnswindowdelegate.h @@ -56,6 +56,7 @@ - (void)windowDidResize:(NSNotification *)notification; - (void)windowDidMove:(NSNotification *)notification; - (void)windowWillClose:(NSNotification *)notification; +- (BOOL)windowShouldClose:(NSNotification *)notification; @end diff --git a/src/plugins/platforms/cocoa/qnswindowdelegate.mm b/src/plugins/platforms/cocoa/qnswindowdelegate.mm index b19a401443..8e17936a78 100644 --- a/src/plugins/platforms/cocoa/qnswindowdelegate.mm +++ b/src/plugins/platforms/cocoa/qnswindowdelegate.mm @@ -80,12 +80,14 @@ } } -- (void)windowWillClose:(NSNotification *)notification +- (BOOL)windowShouldClose:(NSNotification *)notification { Q_UNUSED(notification); if (m_cocoaWindow) { - m_cocoaWindow->windowWillClose(); + return m_cocoaWindow->windowShouldClose(); } + + return YES; } @end -- cgit v1.2.3 From f8e2a8469f91ac1a7daf73c8ed9c24195e5b5a56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Fri, 26 Apr 2013 11:14:21 +0200 Subject: Don't crash on null QCoocaMenuItem. Change-Id: Ia70f616983141134afe874b69a5957e31f6f5ed9 Reviewed-by: Gabriel de Dietrich --- src/plugins/platforms/cocoa/qcocoamenu.mm | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm index 565c77fd44..c5c5c132bc 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.mm +++ b/src/plugins/platforms/cocoa/qcocoamenu.mm @@ -371,7 +371,8 @@ void QCocoaMenu::syncSeparatorsCollapsible(bool enable) NSMenuItem *item = reinterpret_cast([itemArray objectAtIndex:i]); if ([item isSeparatorItem]) { QCocoaMenuItem *cocoaItem = reinterpret_cast([item tag]); - cocoaItem->setVisible(!previousIsSeparator); + if (cocoaItem) + cocoaItem->setVisible(!previousIsSeparator); [item setHidden:previousIsSeparator]; } @@ -384,7 +385,8 @@ void QCocoaMenu::syncSeparatorsCollapsible(bool enable) // We now need to check the final item since we don't want any separators at the end of the list. if (previousItem && previousIsSeparator) { QCocoaMenuItem *cocoaItem = reinterpret_cast([previousItem tag]); - cocoaItem->setVisible(false); + if (cocoaItem) + cocoaItem->setVisible(false); [previousItem setHidden:YES]; } } else { -- cgit v1.2.3 From 7288625c52749f566570a7e7ef047faa8171b18c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Thu, 25 Apr 2013 15:15:20 +0200 Subject: Moving logic from Qt4 for grabbing the X server MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Basically you don't want to grab the X server while your debugging. Also added an environment variable which lets you force to not grab the X server Change-Id: Iba03f11c8f486ce71c55fac7716bffcb7cc8cb98 Reviewed-by: Samuel Rødal --- src/plugins/platforms/xcb/qxcbconnection.cpp | 15 ++++++++++- src/plugins/platforms/xcb/qxcbconnection.h | 5 +++- src/plugins/platforms/xcb/qxcbdrag.cpp | 4 +-- src/plugins/platforms/xcb/qxcbintegration.cpp | 36 ++++++++++++++++++++++++++- 4 files changed, 55 insertions(+), 5 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index de3d487c4b..0597b18679 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -242,8 +242,9 @@ void QXcbConnection::updateScreens() ((QXcbIntegration*)QGuiApplicationPrivate::platformIntegration())->screenAdded(screen); } -QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, const char *displayName) +QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGrabServer, const char *displayName) : m_connection(0) + , m_canGrabServer(canGrabServer) , m_primaryScreen(0) , m_displayName(displayName ? QByteArray(displayName) : qgetenv("DISPLAY")) , m_nativeInterface(nativeInterface) @@ -952,6 +953,18 @@ void QXcbConnection::setFocusWindow(QXcbWindow *w) m_focusWindow = w; } +void QXcbConnection::grabServer() +{ + if (m_canGrabServer) + xcb_grab_server(m_connection); +} + +void QXcbConnection::ungrabServer() +{ + if (m_canGrabServer) + xcb_ungrab_server(m_connection); +} + void QXcbConnection::sendConnectionEvent(QXcbAtom::Atom a, uint id) { xcb_client_message_event_t event; diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index 8ab65fc2bc..27de5a4e83 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -306,7 +306,7 @@ class QXcbConnection : public QObject { Q_OBJECT public: - QXcbConnection(QXcbNativeInterface *nativeInterface, const char *displayName = 0); + QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGrabServer, const char *displayName = 0); ~QXcbConnection(); QXcbConnection *connection() const { return const_cast(this); } @@ -391,6 +391,8 @@ public: QByteArray startupId() const { return m_startupId; } void clearStartupId() { m_startupId.clear(); } + void grabServer(); + void ungrabServer(); private slots: void processXcbEvents(); @@ -454,6 +456,7 @@ private: xcb_connection_t *m_connection; const xcb_setup_t *m_setup; + bool m_canGrabServer; QList m_screens; int m_primaryScreen; diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp index 5dbac93fde..dceac09be5 100644 --- a/src/plugins/platforms/xcb/qxcbdrag.cpp +++ b/src/plugins/platforms/xcb/qxcbdrag.cpp @@ -1160,7 +1160,7 @@ bool QXcbDrag::dndEnable(QXcbWindow *w, bool on) if (desktop_proxy) // *WE* already have one. return false; - xcb_grab_server(xcb_connection()); + connection()->grabServer(); // As per Xdnd4, use XdndProxy xcb_window_t proxy_id = xdndProxy(connection(), w->xcb_window()); @@ -1176,7 +1176,7 @@ bool QXcbDrag::dndEnable(QXcbWindow *w, bool on) XCB_ATOM_WINDOW, 32, 1, &proxy_id); } - xcb_ungrab_server(xcb_connection()); + connection()->ungrabServer(); } else { xdnd_widget = w; } diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp index f0cabea43d..dd1466d23c 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.cpp +++ b/src/plugins/platforms/xcb/qxcbintegration.cpp @@ -91,8 +91,34 @@ #endif #endif +#include + QT_BEGIN_NAMESPACE +#if defined(QT_DEBUG) && defined(Q_OS_LINUX) +// Find out if our parent process is gdb by looking at the 'exe' symlink under /proc,. +// or, for older Linuxes, read out 'cmdline'. +static bool runningUnderDebugger() +{ + const QString parentProc = QLatin1String("/proc/") + QString::number(getppid()); + const QFileInfo parentProcExe(parentProc + QLatin1String("/exe")); + if (parentProcExe.isSymLink()) + return parentProcExe.symLinkTarget().endsWith(QLatin1String("/gdb")); + QFile f(parentProc + QLatin1String("/cmdline")); + if (!f.open(QIODevice::ReadOnly)) + return false; + QByteArray s; + char c; + while (f.getChar(&c) && c) { + if (c == '/') + s.clear(); + else + s += c; + } + return s == "gdb"; +} +#endif + QXcbIntegration::QXcbIntegration(const QStringList ¶meters) : m_eventDispatcher(createUnixEventDispatcher()) , m_services(new QGenericUnixServices) @@ -104,7 +130,15 @@ QXcbIntegration::QXcbIntegration(const QStringList ¶meters) #endif m_nativeInterface.reset(new QXcbNativeInterface); - m_connections << new QXcbConnection(m_nativeInterface.data()); + bool canGrab = true; + #if defined(QT_DEBUG) && defined(Q_OS_LINUX) + canGrab = !runningUnderDebugger(); + #endif + static bool canNotGrabEnv = qgetenv("QT_XCB_NO_GRAB_SERVER").length(); + if (canNotGrabEnv) + canGrab = false; + + m_connections << new QXcbConnection(m_nativeInterface.data(), canGrab); for (int i = 0; i < parameters.size() - 1; i += 2) { #ifdef Q_XCB_DEBUG -- cgit v1.2.3 From fca94fa5ed8321e84e7b0ff515620fbb901db545 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Fri, 26 Apr 2013 08:39:20 +0200 Subject: Add QXcbWindowEventListener MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes it possible to listen for events on xcb_window_t which are not platformwindows inside the xcb plugin Change-Id: Ic9ec17ed757a7f9a5302ef2759c119a72bac573c Reviewed-by: Samuel Rødal --- src/plugins/platforms/xcb/qxcbconnection.cpp | 28 +++++++++++++++-------- src/plugins/platforms/xcb/qxcbconnection.h | 33 +++++++++++++++++++++++---- src/plugins/platforms/xcb/qxcbkeyboard.cpp | 10 ++++++-- src/plugins/platforms/xcb/qxcbkeyboard.h | 4 ++-- src/plugins/platforms/xcb/qxcbwindow.cpp | 17 +++++++++++--- src/plugins/platforms/xcb/qxcbwindow.h | 34 ++++++++++++++++------------ 6 files changed, 90 insertions(+), 36 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 0597b18679..10a8f26614 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -391,28 +391,36 @@ QXcbConnection::~QXcbConnection() delete m_keyboard; } -void QXcbConnection::addWindow(xcb_window_t id, QXcbWindow *window) +void QXcbConnection::addWindowEventListener(xcb_window_t id, QXcbWindowEventListener *eventListener) { - m_mapper.insert(id, window); + m_mapper.insert(id, eventListener); } -void QXcbConnection::removeWindow(xcb_window_t id) +void QXcbConnection::removeWindowEventListener(xcb_window_t id) { m_mapper.remove(id); } -QXcbWindow *QXcbConnection::platformWindowFromId(xcb_window_t id) +QXcbWindowEventListener *QXcbConnection::windowEventListenerFromId(xcb_window_t id) { return m_mapper.value(id, 0); } +QXcbWindow *QXcbConnection::platformWindowFromId(xcb_window_t id) +{ + QXcbWindowEventListener *listener = m_mapper.value(id, 0); + if (listener) + return listener->toWindow(); + return 0; +} + #define HANDLE_PLATFORM_WINDOW_EVENT(event_t, windowMember, handler) \ { \ event_t *e = (event_t *)event; \ - if (QXcbWindow *platformWindow = platformWindowFromId(e->windowMember)) { \ - handled = QWindowSystemInterface::handleNativeEvent(platformWindow->window(), m_nativeInterface->genericEventFilterType(), event, &result); \ + if (QXcbWindowEventListener *eventListener = windowEventListenerFromId(e->windowMember)) { \ + handled = eventListener->handleGenericEvent(event, &result); \ if (!handled) \ - platformWindow->handler(e); \ + eventListener->handler(e); \ } \ } \ break; @@ -420,10 +428,10 @@ break; #define HANDLE_KEYBOARD_EVENT(event_t, handler) \ { \ event_t *e = (event_t *)event; \ - if (QXcbWindow *platformWindow = platformWindowFromId(e->event)) { \ - handled = QWindowSystemInterface::handleNativeEvent(platformWindow->window(), m_nativeInterface->genericEventFilterType(), event, &result); \ + if (QXcbWindowEventListener *eventListener = windowEventListenerFromId(e->event)) { \ + handled = eventListener->handleGenericEvent(event, &result); \ if (!handled) \ - m_keyboard->handler(m_focusWindow ? m_focusWindow : platformWindow, e); \ + m_keyboard->handler(m_focusWindow ? m_focusWindow : eventListener, e); \ } \ } \ break; diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index 27de5a4e83..44c0e28dd5 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -80,8 +80,6 @@ class QXcbClipboard; class QXcbWMSupport; class QXcbNativeInterface; -typedef QHash WindowMapper; - namespace QXcbAtom { enum Atom { // window-manager <-> client protocols @@ -301,6 +299,30 @@ private: XcbPollForQueuedEventFunctionPointer m_xcb_poll_for_queued_event; }; +class QXcbWindowEventListener +{ +public: + virtual bool handleGenericEvent(xcb_generic_event_t *, long *) { return false; } + + virtual void handleExposeEvent(const xcb_expose_event_t *) {} + virtual void handleClientMessageEvent(const xcb_client_message_event_t *) {} + virtual void handleConfigureNotifyEvent(const xcb_configure_notify_event_t *) {} + virtual void handleMapNotifyEvent(const xcb_map_notify_event_t *) {} + virtual void handleUnmapNotifyEvent(const xcb_unmap_notify_event_t *) {} + virtual void handleButtonPressEvent(const xcb_button_press_event_t *) {} + virtual void handleButtonReleaseEvent(const xcb_button_release_event_t *) {} + virtual void handleMotionNotifyEvent(const xcb_motion_notify_event_t *) {} + virtual void handleEnterNotifyEvent(const xcb_enter_notify_event_t *) {} + virtual void handleLeaveNotifyEvent(const xcb_leave_notify_event_t *) {} + virtual void handleFocusInEvent(const xcb_focus_in_event_t *) {} + virtual void handleFocusOutEvent(const xcb_focus_out_event_t *) {} + virtual void handlePropertyNotifyEvent(const xcb_property_notify_event_t *) {} + + virtual QXcbWindow *toWindow() { return 0; } +}; + +typedef QHash WindowMapper; + class QAbstractEventDispatcher; class QXcbConnection : public QObject { @@ -356,8 +378,9 @@ public: void handleXcbError(xcb_generic_error_t *error); void handleXcbEvent(xcb_generic_event_t *event); - void addWindow(xcb_window_t id, QXcbWindow *window); - void removeWindow(xcb_window_t id); + void addWindowEventListener(xcb_window_t id, QXcbWindowEventListener *eventListener); + void removeWindowEventListener(xcb_window_t id); + QXcbWindowEventListener *windowEventListenerFromId(xcb_window_t id); QXcbWindow *platformWindowFromId(xcb_window_t id); xcb_generic_event_t *checkEvent(int type); @@ -393,6 +416,8 @@ public: void grabServer(); void ungrabServer(); + + QXcbNativeInterface *nativeInterface() const { return m_nativeInterface; } private slots: void processXcbEvents(); diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp index 4ac60f6077..51c400ed9c 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp +++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp @@ -1172,14 +1172,20 @@ xcb_keysym_t QXcbKeyboard::lookupString(QWindow *window, uint state, xcb_keycode #endif } -void QXcbKeyboard::handleKeyPressEvent(QXcbWindow *window, const xcb_key_press_event_t *event) +void QXcbKeyboard::handleKeyPressEvent(QXcbWindowEventListener *eventListener, const xcb_key_press_event_t *event) { + QXcbWindow *window = eventListener->toWindow(); + if (!window) + return; window->updateNetWmUserTime(event->time); handleKeyEvent(window->window(), QEvent::KeyPress, event->detail, event->state, event->time); } -void QXcbKeyboard::handleKeyReleaseEvent(QXcbWindow *window, const xcb_key_release_event_t *event) +void QXcbKeyboard::handleKeyReleaseEvent(QXcbWindowEventListener *eventListener, const xcb_key_release_event_t *event) { + QXcbWindow *window = eventListener->toWindow(); + if (!window) + return; handleKeyEvent(window->window(), QEvent::KeyRelease, event->detail, event->state, event->time); } diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.h b/src/plugins/platforms/xcb/qxcbkeyboard.h index da25c51107..3c71daa57f 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.h +++ b/src/plugins/platforms/xcb/qxcbkeyboard.h @@ -58,8 +58,8 @@ public: QXcbKeyboard(QXcbConnection *connection); ~QXcbKeyboard(); - void handleKeyPressEvent(QXcbWindow *window, const xcb_key_press_event_t *event); - void handleKeyReleaseEvent(QXcbWindow *window, const xcb_key_release_event_t *event); + void handleKeyPressEvent(QXcbWindowEventListener *eventListener, const xcb_key_press_event_t *event); + void handleKeyReleaseEvent(QXcbWindowEventListener *eventListener, const xcb_key_release_event_t *event); void handleMappingNotifyEvent(const xcb_mapping_notify_event_t *event); diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 7d6d6a94b3..c845b875bf 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -53,6 +53,7 @@ #include "qxcbkeyboard.h" #include "qxcbwmsupport.h" #include "qxcbimage.h" +#include "qxcbnativeinterface.h" #include @@ -224,7 +225,7 @@ void QXcbWindow::create() m_window = m_screen->root(); m_depth = m_screen->screen()->root_depth; m_imageFormat = imageFormatForDepth(m_depth); - connection()->addWindow(m_window, this); + connection()->addWindowEventListener(m_window, this); return; } @@ -347,7 +348,7 @@ void QXcbWindow::create() 0)); // value list } - connection()->addWindow(m_window, this); + connection()->addWindowEventListener(m_window, this); Q_XCB_CALL(xcb_change_window_attributes(xcb_connection(), m_window, mask, values)); @@ -481,7 +482,7 @@ void QXcbWindow::destroy() xcb_destroy_window(xcb_connection(), m_netWmUserTimeWindow); m_netWmUserTimeWindow = XCB_NONE; } - connection()->removeWindow(m_window); + connection()->removeWindowEventListener(m_window); Q_XCB_CALL(xcb_destroy_window(xcb_connection(), m_window)); m_window = 0; } @@ -1447,6 +1448,14 @@ private: bool m_pending; }; +bool QXcbWindow::handleGenericEvent(xcb_generic_event_t *event, long *result) +{ + return QWindowSystemInterface::handleNativeEvent(window(), + connection()->nativeInterface()->genericEventFilterType(), + event, + result); +} + void QXcbWindow::handleExposeEvent(const xcb_expose_event_t *event) { QRect rect(event->x, event->y, event->width, event->height); @@ -1682,6 +1691,8 @@ void QXcbWindow::handleMotionNotifyEvent(const xcb_motion_notify_event_t *event) handleMouseEvent(event->time, local, global, modifiers); } +QXcbWindow *QXcbWindow::toWindow() { return this; } + void QXcbWindow::handleMouseEvent(xcb_timestamp_t time, const QPoint &local, const QPoint &global, Qt::KeyboardModifiers modifiers) { connection()->setTime(time); diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index 300596845e..5601a115e9 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -56,7 +56,7 @@ QT_BEGIN_NAMESPACE class QXcbScreen; class QXcbEGLSurface; class QIcon; -class QXcbWindow : public QXcbObject, public QPlatformWindow +class QXcbWindow : public QXcbObject, public QXcbWindowEventListener, public QPlatformWindow { public: enum NetWmState { @@ -126,20 +126,24 @@ public: uint depth() const { return m_depth; } QImage::Format imageFormat() const { return m_imageFormat; } - void handleExposeEvent(const xcb_expose_event_t *event); - void handleClientMessageEvent(const xcb_client_message_event_t *event); - void handleConfigureNotifyEvent(const xcb_configure_notify_event_t *event); - void handleMapNotifyEvent(const xcb_map_notify_event_t *event); - void handleUnmapNotifyEvent(const xcb_unmap_notify_event_t *event); - void handleButtonPressEvent(const xcb_button_press_event_t *event); - void handleButtonReleaseEvent(const xcb_button_release_event_t *event); - void handleMotionNotifyEvent(const xcb_motion_notify_event_t *event); - - void handleEnterNotifyEvent(const xcb_enter_notify_event_t *event); - void handleLeaveNotifyEvent(const xcb_leave_notify_event_t *event); - void handleFocusInEvent(const xcb_focus_in_event_t *event); - void handleFocusOutEvent(const xcb_focus_out_event_t *event); - void handlePropertyNotifyEvent(const xcb_property_notify_event_t *event); + bool handleGenericEvent(xcb_generic_event_t *event, long *result) Q_DECL_OVERRIDE; + + void handleExposeEvent(const xcb_expose_event_t *event) Q_DECL_OVERRIDE; + void handleClientMessageEvent(const xcb_client_message_event_t *event) Q_DECL_OVERRIDE; + void handleConfigureNotifyEvent(const xcb_configure_notify_event_t *event) Q_DECL_OVERRIDE; + void handleMapNotifyEvent(const xcb_map_notify_event_t *event) Q_DECL_OVERRIDE; + void handleUnmapNotifyEvent(const xcb_unmap_notify_event_t *event) Q_DECL_OVERRIDE; + void handleButtonPressEvent(const xcb_button_press_event_t *event) Q_DECL_OVERRIDE; + void handleButtonReleaseEvent(const xcb_button_release_event_t *event) Q_DECL_OVERRIDE; + void handleMotionNotifyEvent(const xcb_motion_notify_event_t *event) Q_DECL_OVERRIDE; + + void handleEnterNotifyEvent(const xcb_enter_notify_event_t *event) Q_DECL_OVERRIDE; + void handleLeaveNotifyEvent(const xcb_leave_notify_event_t *event) Q_DECL_OVERRIDE; + void handleFocusInEvent(const xcb_focus_in_event_t *event) Q_DECL_OVERRIDE; + void handleFocusOutEvent(const xcb_focus_out_event_t *event) Q_DECL_OVERRIDE; + void handlePropertyNotifyEvent(const xcb_property_notify_event_t *event) Q_DECL_OVERRIDE; + + QXcbWindow *toWindow() Q_DECL_OVERRIDE; void handleMouseEvent(xcb_timestamp_t time, const QPoint &local, const QPoint &global, Qt::KeyboardModifiers modifiers); -- cgit v1.2.3 From ff9b3fcf6994fa3b3dc8de549298f06023e9a7a8 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 26 Apr 2013 10:05:18 +0200 Subject: iOS: add convenience functions for getting window type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I971df06dd348d1da68578e04076a02e85866e141 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.h | 3 +++ src/plugins/platforms/ios/qioswindow.mm | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index cefb6f9388..2ceb82f0ef 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -96,6 +96,9 @@ private: void raiseOrLower(bool raise); void updateWindowLevel(); bool blockedByModal(); + + inline Qt::WindowType windowType() { return static_cast(int(window()->flags() & Qt::WindowType_Mask)); } + inline bool windowIsPopup() { return windowType() & Qt::Popup & ~Qt::Window; } }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 5edf81af93..c138df8441 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -475,7 +475,7 @@ void QIOSWindow::raiseOrLower(bool raise) void QIOSWindow::updateWindowLevel() { - Qt::WindowType type = static_cast(int(window()->flags() & Qt::WindowType_Mask)); + Qt::WindowType type = windowType(); if (type == Qt::ToolTip) m_windowLevel = 120; @@ -483,7 +483,7 @@ void QIOSWindow::updateWindowLevel() m_windowLevel = 100; else if (window()->isModal()) m_windowLevel = 30; - else if (type & Qt::Popup & ~Qt::Window) + else if (windowIsPopup()) m_windowLevel = 20; else if (type == Qt::Tool) m_windowLevel = 10; -- cgit v1.2.3 From 08f0b5dbc41d67f93c58426d7c8e82f21c9f469b Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 19 Apr 2013 11:20:37 +0200 Subject: iOS: stack true popup windows ontop of tool windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The current implementation would never hit the Qt::Tool case, since a tool is also a Qt::Popup. This patch fixes that by making the logic more explicit. Change-Id: I0e6898081a18289e1007c8a168b374740915b3ff Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.mm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index c138df8441..b173fb786f 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -482,8 +482,10 @@ void QIOSWindow::updateWindowLevel() else if (window()->flags() & Qt::WindowStaysOnTopHint) m_windowLevel = 100; else if (window()->isModal()) + m_windowLevel = 40; + else if (type == Qt::Popup) m_windowLevel = 30; - else if (windowIsPopup()) + else if (type == Qt::SplashScreen) m_windowLevel = 20; else if (type == Qt::Tool) m_windowLevel = 10; -- cgit v1.2.3 From f46a732a4f13ca44cf9fc3a1a8f2c74655fe67c0 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Thu, 18 Apr 2013 11:05:06 +0200 Subject: iOS: remove setMouse/keyboardGrabEnabled warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Setting mouseGrabEnabled means that the window should continue to receive mouse events even when the mouse is not over the application. This is not an issue on iOS, but the warning is still annoying. Change-Id: I0dd7c3828bcb1a51a4eae534aca1da5bfa258f03 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index 2ceb82f0ef..b86dbf7d46 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -77,6 +77,9 @@ public: int effectiveWidth() const; int effectiveHeight() const; + bool setMouseGrabEnabled(bool grab) { return grab; } + bool setKeyboardGrabEnabled(bool grab) { return grab; } + WId winId() const { return WId(m_view); }; QList &touchPoints() { return m_touchPoints; } -- cgit v1.2.3 From fda41c185779dc22a8841509806707776231b6af Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 25 Apr 2013 17:12:07 +0200 Subject: groundwork for making "configure -nomake tools" sane the idea is that "tools" actually means "graphical applications". that means that all bootstrapped/build tools are consistently built, regardless of their location in the source tree. non-bootstrapped non-graphical tools are a bit of a grey area. it's going to be decided on a case-by-case basis. Change-Id: I28b959b7e659d8aa86cf6769ab6d2689c855ec6b Reviewed-by: Joerg Bornemann --- mkspecs/features/qt_build_config.prf | 16 ++++++++++++++++ mkspecs/features/qt_parts.prf | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/mkspecs/features/qt_build_config.prf b/mkspecs/features/qt_build_config.prf index 4cbd08910c..a29e09cbc5 100644 --- a/mkspecs/features/qt_build_config.prf +++ b/mkspecs/features/qt_build_config.prf @@ -50,3 +50,19 @@ CONFIG += \ # Qt modules get compiled without exceptions enabled by default. # However, testcases should be still built with exceptions. exceptions_off testcase_exceptions + + +defineTest(qtBuildPart) { + bp = $$eval($$upper($$section(_QMAKE_CONF_, /, -2, -2))_BUILD_PARTS) + isEmpty(bp): bp = $$QT_BUILD_PARTS + contains(bp, $$1): return(true) + return(false) +} + +defineTest(qtNomakeTools) { + qtBuildPart(tools): return() + for (d, 1) { + $${d}.CONFIG += no_default_target no_default_install + export($${d}.CONFIG) + } +} diff --git a/mkspecs/features/qt_parts.prf b/mkspecs/features/qt_parts.prf index 37dc849f83..cf59ed6e0e 100644 --- a/mkspecs/features/qt_parts.prf +++ b/mkspecs/features/qt_parts.prf @@ -27,7 +27,7 @@ exists($$_PRO_FILE_PWD_/tools/tools.pro) { sub_tools.subdir = tools sub_tools.target = sub-tools sub_tools.depends = sub_src - !contains(QT_BUILD_PARTS, tools): sub_tools.CONFIG = no_default_target no_default_install + # conditional treatment happens on a case-by-case basis SUBDIRS += sub_tools } -- cgit v1.2.3 From f1fd824ebb843d6ca82f2ecdf14eb0112bf2df5e Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 26 Apr 2013 11:59:56 +0200 Subject: make src/ subdir optional there is at least one examples-only repo (qtwebkit-examples). we look for tools/ only when src/ is also present, based on the assumption that if there was only tools/, it would be actually named src/ (like in qttools). the split between the two is nowadays arbitrary anyway. Change-Id: I982b1d0e26dd7d0a5de751546099a58f86390124 Reviewed-by: Joerg Bornemann --- mkspecs/features/qt_parts.prf | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/mkspecs/features/qt_parts.prf b/mkspecs/features/qt_parts.prf index cf59ed6e0e..ed028d59d3 100644 --- a/mkspecs/features/qt_parts.prf +++ b/mkspecs/features/qt_parts.prf @@ -19,22 +19,24 @@ TEMPLATE = subdirs bp = $$eval($$upper($$TARGET)_BUILD_PARTS) !isEmpty(bp): QT_BUILD_PARTS = $$bp -sub_src.subdir = src -sub_src.target = sub-src -SUBDIRS = sub_src +exists($$_PRO_FILE_PWD_/src/src.pro) { + sub_src.subdir = src + sub_src.target = sub-src + SUBDIRS += sub_src -exists($$_PRO_FILE_PWD_/tools/tools.pro) { - sub_tools.subdir = tools - sub_tools.target = sub-tools - sub_tools.depends = sub_src - # conditional treatment happens on a case-by-case basis - SUBDIRS += sub_tools + exists($$_PRO_FILE_PWD_/tools/tools.pro) { + sub_tools.subdir = tools + sub_tools.target = sub-tools + sub_tools.depends = sub_src + # conditional treatment happens on a case-by-case basis + SUBDIRS += sub_tools + } } exists($$_PRO_FILE_PWD_/examples/examples.pro) { sub_examples.subdir = examples sub_examples.target = sub-examples - sub_examples.depends = sub_src + contains(SUBDIRS, sub_src): sub_examples.depends = sub_src examples_need_tools: sub_examples.depends += sub_tools !contains(QT_BUILD_PARTS, examples): sub_examples.CONFIG = no_default_target no_default_install SUBDIRS += sub_examples @@ -44,7 +46,7 @@ exists($$_PRO_FILE_PWD_/examples/examples.pro) { exists($$_PRO_FILE_PWD_/demos/demos.pro) { sub_demos.subdir = demos sub_demos.target = sub-demos - sub_demos.depends = sub_src + contains(SUBDIRS, sub_src): sub_demos.depends = sub_src examples_need_tools: sub_demos.depends += sub_tools !contains(QT_BUILD_PARTS, examples): sub_demos.CONFIG = no_default_target no_default_install SUBDIRS += sub_demos @@ -53,7 +55,7 @@ exists($$_PRO_FILE_PWD_/demos/demos.pro) { exists($$_PRO_FILE_PWD_/tests/tests.pro) { sub_tests.subdir = tests sub_tests.target = sub-tests - sub_tests.depends = sub_src # The tests may have a run-time only dependency on other parts + contains(SUBDIRS, sub_src): sub_tests.depends = sub_src # The tests may have a run-time only dependency on other parts tests_need_tools: sub_tests.depends += sub_tools sub_tests.CONFIG = no_default_install !contains(QT_BUILD_PARTS, tests) { -- cgit v1.2.3 From 940f7c8744db8fe8b4002019550ca383a1cf5d3f Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 26 Apr 2013 14:15:34 +0200 Subject: split qt_app.prf out of qt_tool.prf this way we can use it for "regular" apps (gui tools) as well. Change-Id: I3b00d0bde215dff1c2726b35626c4c0c256d92c2 Reviewed-by: Joerg Bornemann --- mkspecs/features/qt_app.prf | 34 ++++++++++++++++++++++++++++++++++ mkspecs/features/qt_tool.prf | 23 +---------------------- 2 files changed, 35 insertions(+), 22 deletions(-) create mode 100644 mkspecs/features/qt_app.prf diff --git a/mkspecs/features/qt_app.prf b/mkspecs/features/qt_app.prf new file mode 100644 index 0000000000..8758f4a9a0 --- /dev/null +++ b/mkspecs/features/qt_app.prf @@ -0,0 +1,34 @@ +# +# W A R N I N G +# ------------- +# +# This file is not part of the Qt API. It exists purely as an +# implementation detail. It may change from version to version +# without notice, or even be removed. +# +# We mean it. +# + +TEMPLATE = app + +load(qt_build_paths) +DESTDIR = $$MODULE_BASE_OUTDIR/bin + +isEmpty(QMAKE_INFO_PLIST): CONFIG -= app_bundle + +host_build: QT -= gui # no host tool will ever use gui +host_build:force_bootstrap { + !build_pass: CONFIG += release + contains(QT, core(-private)?|xml) { + QT -= core core-private xml + QT += bootstrap-private + } + target.path = $$[QT_HOST_BINS] +} else { + !build_pass:contains(QT_CONFIG, build_all): CONFIG += release + target.path = $$[QT_INSTALL_BINS] +} +INSTALLS += target + +load(qt_targets) +load(qt_common) diff --git a/mkspecs/features/qt_tool.prf b/mkspecs/features/qt_tool.prf index 46d031fb32..0a588807c8 100644 --- a/mkspecs/features/qt_tool.prf +++ b/mkspecs/features/qt_tool.prf @@ -9,30 +9,9 @@ # We mean it. # -TEMPLATE = app - -load(qt_build_paths) -DESTDIR = $$MODULE_BASE_OUTDIR/bin +load(qt_app) CONFIG += console -isEmpty(QMAKE_INFO_PLIST): CONFIG -= app_bundle - -host_build: QT -= gui # no host tool will ever use gui -host_build:force_bootstrap { - !build_pass: CONFIG += release - contains(QT, core(-private)?|xml) { - QT -= core core-private xml - QT += bootstrap-private - } - target.path = $$[QT_HOST_BINS] -} else { - !build_pass:contains(QT_CONFIG, build_all): CONFIG += release - target.path = $$[QT_INSTALL_BINS] -} -INSTALLS += target - -load(qt_targets) -load(qt_common) # If we are doing a prefix build, create a "module" pri which enables # qtPrepareTool() to work with the non-installed build. -- cgit v1.2.3 From 53ac80c50c0711d39ee4e6f41eb7427891670d60 Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Fri, 26 Apr 2013 16:30:47 +0200 Subject: Android: fix crash on exit QTouchDevice is already automatically deleted at shutdown. Task-number: QTBUG-30847 Change-Id: Id6a407083efed849a34ccb1caa315204fc5a5891 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 3de6c47ad0..f0630b5224 100644 --- a/src/plugins/platforms/android/src/qandroidplatformintegration.cpp +++ b/src/plugins/platforms/android/src/qandroidplatformintegration.cpp @@ -183,7 +183,6 @@ QAndroidPlatformIntegration::~QAndroidPlatformIntegration() { delete m_androidPlatformNativeInterface; delete m_androidFDB; - delete m_touchDevice; QtAndroid::setAndroidPlatformIntegration(NULL); } QPlatformFontDatabase *QAndroidPlatformIntegration::fontDatabase() const -- cgit v1.2.3 From 3511b199ddbd423b2c159887b27f4eba1a3182d1 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Mon, 22 Apr 2013 23:39:27 +0200 Subject: Define QMAKE_CXXFLAGS_RTTI_{ON|OFF} for aix-xlc mkspec Task-number: QTBUG-26393 Change-Id: I2d676ad6004c3fad2ef0a3ab990d6e120ed7f73c Reviewed-by: Oswald Buddenhagen --- mkspecs/aix-xlc/qmake.conf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mkspecs/aix-xlc/qmake.conf b/mkspecs/aix-xlc/qmake.conf index adcac80ea1..c4efebff24 100644 --- a/mkspecs/aix-xlc/qmake.conf +++ b/mkspecs/aix-xlc/qmake.conf @@ -34,6 +34,8 @@ 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_RTTI_ON = -qrtti +QMAKE_CXXFLAGS_RTTI_OFF = -qnortti QMAKE_COMPILER_DEFINES += __xlC__ QMAKE_INCDIR = -- cgit v1.2.3 From c29cbfa8586e227ed31bf248ddbd15429ab54ac6 Mon Sep 17 00:00:00 2001 From: Jan Arve Saether Date: Fri, 26 Apr 2013 14:21:24 +0200 Subject: Get rid of this hack where QAccessible inherits from QObject. This was added just so that moc could pick up the enums and so that we could use the enums in Q_PROPERTY declarations, which was needed for accessibility in QML. It turns out that Q_GADGET is enough for us. This is a strictly a binary compatible change. However, QAccessible was marked internal in 5.0, so we are free to change it. In addition, this class is static and cannot be instantiated. Change-Id: I27e2e97c5f4b45c38678264c6b593a4383db8d3e Reviewed-by: Frederik Gladhorn --- src/gui/accessible/qaccessible.h | 5 +--- .../auto/bic/data/QtGui.5.0.0.linux-gcc-amd64.txt | 31 +++------------------- tests/auto/bic/data/QtGui.5.0.0.linux-gcc-ia32.txt | 31 +++------------------- .../bic/data/QtOpenGL.5.0.0.linux-gcc-amd64.txt | 31 +++------------------- .../bic/data/QtOpenGL.5.0.0.linux-gcc-ia32.txt | 31 +++------------------- .../data/QtPrintSupport.5.0.0.linux-gcc-amd64.txt | 31 +++------------------- .../data/QtPrintSupport.5.0.0.linux-gcc-ia32.txt | 31 +++------------------- .../bic/data/QtWidgets.5.0.0.linux-gcc-amd64.txt | 31 +++------------------- .../bic/data/QtWidgets.5.0.0.linux-gcc-ia32.txt | 31 +++------------------- 9 files changed, 25 insertions(+), 228 deletions(-) diff --git a/src/gui/accessible/qaccessible.h b/src/gui/accessible/qaccessible.h index 339e3fbcd6..283209d08f 100644 --- a/src/gui/accessible/qaccessible.h +++ b/src/gui/accessible/qaccessible.h @@ -66,11 +66,8 @@ class QTextCursor; // We need to inherit QObject to expose the enums to QML. class Q_GUI_EXPORT QAccessible -#ifndef Q_QDOC - :public QObject -#endif { - Q_OBJECT + Q_GADGET Q_ENUMS(Role Event State) public: diff --git a/tests/auto/bic/data/QtGui.5.0.0.linux-gcc-amd64.txt b/tests/auto/bic/data/QtGui.5.0.0.linux-gcc-amd64.txt index d2db7b0a8f..6a7d5535fb 100644 --- a/tests/auto/bic/data/QtGui.5.0.0.linux-gcc-amd64.txt +++ b/tests/auto/bic/data/QtGui.5.0.0.linux-gcc-amd64.txt @@ -3981,40 +3981,15 @@ QScreenOrientationChangeEvent (0x7f7180294bc8) 0 QEvent (0x7f71806522a0) 0 primary-for QScreenOrientationChangeEvent (0x7f7180294bc8) -Class QAccessible::QPrivateSignal - size=1 align=1 - base size=0 base align=1 -QAccessible::QPrivateSignal (0x7f7180652360) 0 empty - Class QAccessible::State size=8 align=8 base size=5 base align=8 QAccessible::State (0x7f71806523c0) 0 -Vtable for QAccessible -QAccessible::_ZTV11QAccessible: 14u entries -0 (int (*)(...))0 -8 (int (*)(...))(& _ZTI11QAccessible) -16 (int (*)(...))QAccessible::metaObject -24 (int (*)(...))QAccessible::qt_metacast -32 (int (*)(...))QAccessible::qt_metacall -40 (int (*)(...))QAccessible::~QAccessible -48 (int (*)(...))QAccessible::~QAccessible -56 (int (*)(...))QObject::event -64 (int (*)(...))QObject::eventFilter -72 (int (*)(...))QObject::timerEvent -80 (int (*)(...))QObject::childEvent -88 (int (*)(...))QObject::customEvent -96 (int (*)(...))QObject::connectNotify -104 (int (*)(...))QObject::disconnectNotify - Class QAccessible - size=16 align=8 - base size=16 base align=8 -QAccessible (0x7f7180294d68) 0 - vptr=((& QAccessible::_ZTV11QAccessible) + 16u) - QObject (0x7f7180652300) 0 - primary-for QAccessible (0x7f7180294d68) + size=1 align=1 + base size=0 base align=1 +QAccessible (0x7f7180294d68) 0 empty Vtable for QAccessibleInterface QAccessibleInterface::_ZTV20QAccessibleInterface: 23u entries diff --git a/tests/auto/bic/data/QtGui.5.0.0.linux-gcc-ia32.txt b/tests/auto/bic/data/QtGui.5.0.0.linux-gcc-ia32.txt index 433c0eaacc..33fb2fd8a0 100644 --- a/tests/auto/bic/data/QtGui.5.0.0.linux-gcc-ia32.txt +++ b/tests/auto/bic/data/QtGui.5.0.0.linux-gcc-ia32.txt @@ -3981,40 +3981,15 @@ QScreenOrientationChangeEvent (0xb3a816cc) 0 QEvent (0xb392ecb0) 0 primary-for QScreenOrientationChangeEvent (0xb3a816cc) -Class QAccessible::QPrivateSignal - size=1 align=1 - base size=0 base align=1 -QAccessible::QPrivateSignal (0xb392ee70) 0 empty - Class QAccessible::State size=8 align=4 base size=5 base align=4 QAccessible::State (0xb392eea8) 0 -Vtable for QAccessible -QAccessible::_ZTV11QAccessible: 14u entries -0 (int (*)(...))0 -4 (int (*)(...))(& _ZTI11QAccessible) -8 (int (*)(...))QAccessible::metaObject -12 (int (*)(...))QAccessible::qt_metacast -16 (int (*)(...))QAccessible::qt_metacall -20 (int (*)(...))QAccessible::~QAccessible -24 (int (*)(...))QAccessible::~QAccessible -28 (int (*)(...))QObject::event -32 (int (*)(...))QObject::eventFilter -36 (int (*)(...))QObject::timerEvent -40 (int (*)(...))QObject::childEvent -44 (int (*)(...))QObject::customEvent -48 (int (*)(...))QObject::connectNotify -52 (int (*)(...))QObject::disconnectNotify - Class QAccessible - size=8 align=4 - base size=8 base align=4 -QAccessible (0xb3a81708) 0 - vptr=((& QAccessible::_ZTV11QAccessible) + 8u) - QObject (0xb392ed90) 0 - primary-for QAccessible (0xb3a81708) + size=1 align=1 + base size=0 base align=1 +QAccessible (0xb3a81708) 0 empty Vtable for QAccessibleInterface QAccessibleInterface::_ZTV20QAccessibleInterface: 23u entries diff --git a/tests/auto/bic/data/QtOpenGL.5.0.0.linux-gcc-amd64.txt b/tests/auto/bic/data/QtOpenGL.5.0.0.linux-gcc-amd64.txt index 125e529c33..ebf0273f77 100644 --- a/tests/auto/bic/data/QtOpenGL.5.0.0.linux-gcc-amd64.txt +++ b/tests/auto/bic/data/QtOpenGL.5.0.0.linux-gcc-amd64.txt @@ -3981,40 +3981,15 @@ QScreenOrientationChangeEvent (0x7f04b8f8bbc8) 0 QEvent (0x7f04b8efe720) 0 primary-for QScreenOrientationChangeEvent (0x7f04b8f8bbc8) -Class QAccessible::QPrivateSignal - size=1 align=1 - base size=0 base align=1 -QAccessible::QPrivateSignal (0x7f04b8efe7e0) 0 empty - Class QAccessible::State size=8 align=8 base size=5 base align=8 QAccessible::State (0x7f04b8efe840) 0 -Vtable for QAccessible -QAccessible::_ZTV11QAccessible: 14u entries -0 (int (*)(...))0 -8 (int (*)(...))(& _ZTI11QAccessible) -16 (int (*)(...))QAccessible::metaObject -24 (int (*)(...))QAccessible::qt_metacast -32 (int (*)(...))QAccessible::qt_metacall -40 (int (*)(...))QAccessible::~QAccessible -48 (int (*)(...))QAccessible::~QAccessible -56 (int (*)(...))QObject::event -64 (int (*)(...))QObject::eventFilter -72 (int (*)(...))QObject::timerEvent -80 (int (*)(...))QObject::childEvent -88 (int (*)(...))QObject::customEvent -96 (int (*)(...))QObject::connectNotify -104 (int (*)(...))QObject::disconnectNotify - Class QAccessible - size=16 align=8 - base size=16 base align=8 -QAccessible (0x7f04b8f8bd68) 0 - vptr=((& QAccessible::_ZTV11QAccessible) + 16u) - QObject (0x7f04b8efe780) 0 - primary-for QAccessible (0x7f04b8f8bd68) + size=1 align=1 + base size=0 base align=1 +QAccessible (0x7f04b8f8bd68) 0 empty Vtable for QAccessibleInterface QAccessibleInterface::_ZTV20QAccessibleInterface: 23u entries diff --git a/tests/auto/bic/data/QtOpenGL.5.0.0.linux-gcc-ia32.txt b/tests/auto/bic/data/QtOpenGL.5.0.0.linux-gcc-ia32.txt index 7d8a99d222..8ced43438f 100644 --- a/tests/auto/bic/data/QtOpenGL.5.0.0.linux-gcc-ia32.txt +++ b/tests/auto/bic/data/QtOpenGL.5.0.0.linux-gcc-ia32.txt @@ -3981,40 +3981,15 @@ QScreenOrientationChangeEvent (0xb3b78e10) 0 QEvent (0xb39dbe38) 0 primary-for QScreenOrientationChangeEvent (0xb3b78e10) -Class QAccessible::QPrivateSignal - size=1 align=1 - base size=0 base align=1 -QAccessible::QPrivateSignal (0xb39dba48) 0 empty - Class QAccessible::State size=8 align=4 base size=5 base align=4 QAccessible::State (0xb39dbe00) 0 -Vtable for QAccessible -QAccessible::_ZTV11QAccessible: 14u entries -0 (int (*)(...))0 -4 (int (*)(...))(& _ZTI11QAccessible) -8 (int (*)(...))QAccessible::metaObject -12 (int (*)(...))QAccessible::qt_metacast -16 (int (*)(...))QAccessible::qt_metacall -20 (int (*)(...))QAccessible::~QAccessible -24 (int (*)(...))QAccessible::~QAccessible -28 (int (*)(...))QObject::event -32 (int (*)(...))QObject::eventFilter -36 (int (*)(...))QObject::timerEvent -40 (int (*)(...))QObject::childEvent -44 (int (*)(...))QObject::customEvent -48 (int (*)(...))QObject::connectNotify -52 (int (*)(...))QObject::disconnectNotify - Class QAccessible - size=8 align=4 - base size=8 base align=4 -QAccessible (0xb3b78e4c) 0 - vptr=((& QAccessible::_ZTV11QAccessible) + 8u) - QObject (0xb39dbf18) 0 - primary-for QAccessible (0xb3b78e4c) + size=1 align=1 + base size=0 base align=1 +QAccessible (0xb3b78e4c) 0 empty Vtable for QAccessibleInterface QAccessibleInterface::_ZTV20QAccessibleInterface: 23u entries diff --git a/tests/auto/bic/data/QtPrintSupport.5.0.0.linux-gcc-amd64.txt b/tests/auto/bic/data/QtPrintSupport.5.0.0.linux-gcc-amd64.txt index 20988597b1..28a8468405 100644 --- a/tests/auto/bic/data/QtPrintSupport.5.0.0.linux-gcc-amd64.txt +++ b/tests/auto/bic/data/QtPrintSupport.5.0.0.linux-gcc-amd64.txt @@ -3986,40 +3986,15 @@ QScreenOrientationChangeEvent (0x7f0bd5ed8bc8) 0 QEvent (0x7f0bd5e7e300) 0 primary-for QScreenOrientationChangeEvent (0x7f0bd5ed8bc8) -Class QAccessible::QPrivateSignal - size=1 align=1 - base size=0 base align=1 -QAccessible::QPrivateSignal (0x7f0bd5e7e3c0) 0 empty - Class QAccessible::State size=8 align=8 base size=5 base align=8 QAccessible::State (0x7f0bd5e7e420) 0 -Vtable for QAccessible -QAccessible::_ZTV11QAccessible: 14u entries -0 (int (*)(...))0 -8 (int (*)(...))(& _ZTI11QAccessible) -16 (int (*)(...))QAccessible::metaObject -24 (int (*)(...))QAccessible::qt_metacast -32 (int (*)(...))QAccessible::qt_metacall -40 (int (*)(...))QAccessible::~QAccessible -48 (int (*)(...))QAccessible::~QAccessible -56 (int (*)(...))QObject::event -64 (int (*)(...))QObject::eventFilter -72 (int (*)(...))QObject::timerEvent -80 (int (*)(...))QObject::childEvent -88 (int (*)(...))QObject::customEvent -96 (int (*)(...))QObject::connectNotify -104 (int (*)(...))QObject::disconnectNotify - Class QAccessible - size=16 align=8 - base size=16 base align=8 -QAccessible (0x7f0bd5ed8d68) 0 - vptr=((& QAccessible::_ZTV11QAccessible) + 16u) - QObject (0x7f0bd5e7e360) 0 - primary-for QAccessible (0x7f0bd5ed8d68) + size=1 align=1 + base size=0 base align=1 +QAccessible (0x7f0bd5ed8d68) 0 empty Vtable for QAccessibleInterface QAccessibleInterface::_ZTV20QAccessibleInterface: 23u entries diff --git a/tests/auto/bic/data/QtPrintSupport.5.0.0.linux-gcc-ia32.txt b/tests/auto/bic/data/QtPrintSupport.5.0.0.linux-gcc-ia32.txt index 6162fcde57..be5a9dc941 100644 --- a/tests/auto/bic/data/QtPrintSupport.5.0.0.linux-gcc-ia32.txt +++ b/tests/auto/bic/data/QtPrintSupport.5.0.0.linux-gcc-ia32.txt @@ -3981,40 +3981,15 @@ QScreenOrientationChangeEvent (0xb3b227bc) 0 QEvent (0xb39d0e38) 0 primary-for QScreenOrientationChangeEvent (0xb3b227bc) -Class QAccessible::QPrivateSignal - size=1 align=1 - base size=0 base align=1 -QAccessible::QPrivateSignal (0xb39d0a48) 0 empty - Class QAccessible::State size=8 align=4 base size=5 base align=4 QAccessible::State (0xb39d0e00) 0 -Vtable for QAccessible -QAccessible::_ZTV11QAccessible: 14u entries -0 (int (*)(...))0 -4 (int (*)(...))(& _ZTI11QAccessible) -8 (int (*)(...))QAccessible::metaObject -12 (int (*)(...))QAccessible::qt_metacast -16 (int (*)(...))QAccessible::qt_metacall -20 (int (*)(...))QAccessible::~QAccessible -24 (int (*)(...))QAccessible::~QAccessible -28 (int (*)(...))QObject::event -32 (int (*)(...))QObject::eventFilter -36 (int (*)(...))QObject::timerEvent -40 (int (*)(...))QObject::childEvent -44 (int (*)(...))QObject::customEvent -48 (int (*)(...))QObject::connectNotify -52 (int (*)(...))QObject::disconnectNotify - Class QAccessible - size=8 align=4 - base size=8 base align=4 -QAccessible (0xb3b227f8) 0 - vptr=((& QAccessible::_ZTV11QAccessible) + 8u) - QObject (0xb39d0f18) 0 - primary-for QAccessible (0xb3b227f8) + size=1 align=1 + base size=0 base align=1 +QAccessible (0xb3b227f8) 0 empty Vtable for QAccessibleInterface QAccessibleInterface::_ZTV20QAccessibleInterface: 23u entries diff --git a/tests/auto/bic/data/QtWidgets.5.0.0.linux-gcc-amd64.txt b/tests/auto/bic/data/QtWidgets.5.0.0.linux-gcc-amd64.txt index 35a4d3a30a..d89eb8d488 100644 --- a/tests/auto/bic/data/QtWidgets.5.0.0.linux-gcc-amd64.txt +++ b/tests/auto/bic/data/QtWidgets.5.0.0.linux-gcc-amd64.txt @@ -3981,40 +3981,15 @@ QScreenOrientationChangeEvent (0x7f871fa70bc8) 0 QEvent (0x7f871fa15300) 0 primary-for QScreenOrientationChangeEvent (0x7f871fa70bc8) -Class QAccessible::QPrivateSignal - size=1 align=1 - base size=0 base align=1 -QAccessible::QPrivateSignal (0x7f871fa153c0) 0 empty - Class QAccessible::State size=8 align=8 base size=5 base align=8 QAccessible::State (0x7f871fa15420) 0 -Vtable for QAccessible -QAccessible::_ZTV11QAccessible: 14u entries -0 (int (*)(...))0 -8 (int (*)(...))(& _ZTI11QAccessible) -16 (int (*)(...))QAccessible::metaObject -24 (int (*)(...))QAccessible::qt_metacast -32 (int (*)(...))QAccessible::qt_metacall -40 (int (*)(...))QAccessible::~QAccessible -48 (int (*)(...))QAccessible::~QAccessible -56 (int (*)(...))QObject::event -64 (int (*)(...))QObject::eventFilter -72 (int (*)(...))QObject::timerEvent -80 (int (*)(...))QObject::childEvent -88 (int (*)(...))QObject::customEvent -96 (int (*)(...))QObject::connectNotify -104 (int (*)(...))QObject::disconnectNotify - Class QAccessible - size=16 align=8 - base size=16 base align=8 -QAccessible (0x7f871fa70d68) 0 - vptr=((& QAccessible::_ZTV11QAccessible) + 16u) - QObject (0x7f871fa15360) 0 - primary-for QAccessible (0x7f871fa70d68) + size=1 align=1 + base size=0 base align=1 +QAccessible (0x7f871fa70d68) 0 empty Vtable for QAccessibleInterface QAccessibleInterface::_ZTV20QAccessibleInterface: 23u entries diff --git a/tests/auto/bic/data/QtWidgets.5.0.0.linux-gcc-ia32.txt b/tests/auto/bic/data/QtWidgets.5.0.0.linux-gcc-ia32.txt index fe8f00314f..b1b1eb5c38 100644 --- a/tests/auto/bic/data/QtWidgets.5.0.0.linux-gcc-ia32.txt +++ b/tests/auto/bic/data/QtWidgets.5.0.0.linux-gcc-ia32.txt @@ -3981,40 +3981,15 @@ QScreenOrientationChangeEvent (0xb3ae37bc) 0 QEvent (0xb3990e38) 0 primary-for QScreenOrientationChangeEvent (0xb3ae37bc) -Class QAccessible::QPrivateSignal - size=1 align=1 - base size=0 base align=1 -QAccessible::QPrivateSignal (0xb3990a48) 0 empty - Class QAccessible::State size=8 align=4 base size=5 base align=4 QAccessible::State (0xb3990e00) 0 -Vtable for QAccessible -QAccessible::_ZTV11QAccessible: 14u entries -0 (int (*)(...))0 -4 (int (*)(...))(& _ZTI11QAccessible) -8 (int (*)(...))QAccessible::metaObject -12 (int (*)(...))QAccessible::qt_metacast -16 (int (*)(...))QAccessible::qt_metacall -20 (int (*)(...))QAccessible::~QAccessible -24 (int (*)(...))QAccessible::~QAccessible -28 (int (*)(...))QObject::event -32 (int (*)(...))QObject::eventFilter -36 (int (*)(...))QObject::timerEvent -40 (int (*)(...))QObject::childEvent -44 (int (*)(...))QObject::customEvent -48 (int (*)(...))QObject::connectNotify -52 (int (*)(...))QObject::disconnectNotify - Class QAccessible - size=8 align=4 - base size=8 base align=4 -QAccessible (0xb3ae37f8) 0 - vptr=((& QAccessible::_ZTV11QAccessible) + 8u) - QObject (0xb3990f18) 0 - primary-for QAccessible (0xb3ae37f8) + size=1 align=1 + base size=0 base align=1 +QAccessible (0xb3ae37f8) 0 empty Vtable for QAccessibleInterface QAccessibleInterface::_ZTV20QAccessibleInterface: 23u entries -- cgit v1.2.3 From a9c8eb5a0a8d24f6f4c072ff89f6c40476ea4f89 Mon Sep 17 00:00:00 2001 From: Sergio Ahumada Date: Thu, 25 Apr 2013 12:28:47 +0200 Subject: README: Update the README file Change-Id: I33d73c7af46a22beb082b16d5b0775e9cdfd0f27 Reviewed-by: Iikka Eklund Reviewed-by: Sergio Ahumada --- dist/README | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/dist/README b/dist/README index 19443c1bbe..6332d12c34 100644 --- a/dist/README +++ b/dist/README @@ -58,11 +58,12 @@ Directory Structure ------------------- The default top-level installation directory is the directory "Qt" in -your home directory, but you can specify another directory (). Each -Qt version is installed in the / directory. This -directory contains subdirectories for the Qt libraries (), -documentation (doc), and sources (src). The directory contains -subdirectories for development tools (bin) and examples. +your home directory, but you can specify another directory (). On +Windows, however, the default top-level installation directory is "C:\Qt\Qt". +Each Qt version is installed in the / directory. This directory +contains subdirectories for the Qt libraries () and sources (Src). +The directory contains subdirectories for development tools (bin) and +examples. Starting Development Tools @@ -80,25 +81,21 @@ the command line. You can also launch some of them as standalone applications. For example: - Qt Assistant, the Qt documentation reader -- qmlscene, the viewer for Qt Quick2 declarative QML applications -- QMLViewer, the viewer for Qt Quick1 declarative QML applications -- Qt Designer, the GUI designer for Qt widgets-based applications +- Qt QML Scene, the viewer for Qt Quick 2 files +- Qt QML Viewer, the viewer for Qt Quick 1 files +and - Qt Designer, the GUI designer for Qt widgets-based applications +You can use Qt Creator to develop with other Qt versions as well: -Running Example Applications ----------------------------- - -You can open example applications in the Qt Creator Welcome mode to build and -run them. + http://qt-project.org/doc/qtcreator-2.6/creator-project-qmake.html -The QML based Quick 2 examples are located in -///examples/qtdeclarative. You can load them -using the qmlscene application. -The QML based Quick 1 examples are located in -///examples/qtquick1. You can view them with the -QMLViewer application. +Running Example Applications +---------------------------- +You can open most example applications in the Qt Creator Welcome mode to build +and run them. Additional examples can be opened by browsing +///examples. Building Qt 5 from Source ------------------------- -- cgit v1.2.3 From 3d42f6fed220cd0cd24924eb55db4b2751eed74c Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Thu, 25 Apr 2013 13:06:53 +0200 Subject: QFlags: Remove text promising 64 bit enums for 5.1 Change-Id: I34173abd693cb124beb8feec5e0cee1f7842725e Reviewed-by: Olivier Goffart --- src/corelib/global/qflags.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/global/qflags.h b/src/corelib/global/qflags.h index 4722fe2282..6332e2d761 100644 --- a/src/corelib/global/qflags.h +++ b/src/corelib/global/qflags.h @@ -79,7 +79,7 @@ class QFlags { Q_STATIC_ASSERT_X((sizeof(Enum) <= sizeof(int)), "QFlags uses an int as storage, so an enum with underlying " - "long long would overflow. Qt 5.1 will have support for 64bit enums."); + "long long will overflow."); struct Private; typedef int (Private::*Zero); public: -- cgit v1.2.3 From a298216bb4383dbe96688dfb80da0cd875766de0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Fri, 26 Apr 2013 10:36:04 +0200 Subject: Prevent crash due to giving QWidget::update() a large rect. We can simply clip the update rect against the widget's rect and return if it's empty. Otherwise we risk ending up with update rects that are larger than INT_MAX due to multiple update rects being merged. Task-number: QTBUG-30876 Change-Id: I23bd0149fbe8d1a007a60b228e6bddb45dc4fc32 Reviewed-by: Thiago Macieira Reviewed-by: Gunnar Sletta --- src/widgets/kernel/qwidget.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 3b796fe35b..cb7761add7 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -9874,11 +9874,16 @@ void QWidget::update() */ void QWidget::update(const QRect &rect) { - if (!isVisible() || !updatesEnabled() || rect.isEmpty()) + if (!isVisible() || !updatesEnabled()) + return; + + QRect r = rect & QWidget::rect(); + + if (r.isEmpty()) return; if (testAttribute(Qt::WA_WState_InPaintEvent)) { - QApplication::postEvent(this, new QUpdateLaterEvent(rect)); + QApplication::postEvent(this, new QUpdateLaterEvent(r)); return; } @@ -9891,9 +9896,9 @@ void QWidget::update(const QRect &rect) #endif // Q_WS_MAC QTLWExtra *tlwExtra = window()->d_func()->maybeTopData(); if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) - tlwExtra->backingStoreTracker->markDirty(rect, this); + tlwExtra->backingStoreTracker->markDirty(r, this); } else { - d_func()->repaint_sys(rect); + d_func()->repaint_sys(r); } } -- cgit v1.2.3 From 7f943968ade6a65321d4a00822f5b3a034a19e0c Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Tue, 23 Apr 2013 15:09:34 +0200 Subject: Fix QKeySequence matching QKeySequence failed to find a match in the shortcut table when QKeyEvent contained Qt::GroupSwitchModifier modifier. It's not a part of the shortcut, it simply shifts character group in a keyboard mapping table. Task-number: QTBUG-26302 Change-Id: Id91cd4999777f7085068e9dba5cb22b40653e23d Reviewed-by: David Faure (KDE) Reviewed-by: Friedemann Kleint --- src/gui/kernel/qevent.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index 4f1f7d838f..c5be379b7d 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -966,7 +966,7 @@ QKeyEvent::~QKeyEvent() \sa QApplication::keyboardModifiers() */ -//###### We must check with XGetModifierMapping + Qt::KeyboardModifiers QKeyEvent::modifiers() const { if (key() == Qt::Key_Shift) @@ -977,6 +977,8 @@ Qt::KeyboardModifiers QKeyEvent::modifiers() const return Qt::KeyboardModifiers(QInputEvent::modifiers()^Qt::AltModifier); if (key() == Qt::Key_Meta) return Qt::KeyboardModifiers(QInputEvent::modifiers()^Qt::MetaModifier); + if (key() == Qt::Key_AltGr) + return Qt::KeyboardModifiers(QInputEvent::modifiers()^Qt::GroupSwitchModifier); return QInputEvent::modifiers(); } @@ -990,10 +992,10 @@ Qt::KeyboardModifiers QKeyEvent::modifiers() const */ bool QKeyEvent::matches(QKeySequence::StandardKey matchKey) const { - uint searchkey = (modifiers() | key()) & ~(Qt::KeypadModifier); //The keypad modifier should not make a difference + //The keypad and group switch modifier should not make a difference + uint searchkey = (modifiers() | key()) & ~(Qt::KeypadModifier | Qt::GroupSwitchModifier); const uint platform = QKeySequencePrivate::currentKeyPlatforms(); - uint N = QKeySequencePrivate::numberOfKeyBindings; int first = 0; int last = N - 1; -- cgit v1.2.3