summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2020-02-26 01:00:25 +0100
committerEdward Welbourne <edward.welbourne@qt.io>2020-02-26 18:39:21 +0100
commit75c0ffaf6d2b92cdf26092e01acdd5af4afeac97 (patch)
treebb9e85c21248790ec99b3665928872e39b14db64
parent4753d69d8934258de7fb64550e50a5cbb9b5603f (diff)
parent462c2745a5168a5b57381d05779b5d16aebe018e (diff)
Merge remote-tracking branch 'origin/5.15' into dev
Conflicts: examples/network/bearermonitor/CMakeLists.txt examples/network/CMakeLists.txt src/corelib/tools/qlinkedlist.h src/sql/kernel/qsqldriver_p.h src/sql/kernel/qsqlresult_p.h src/widgets/kernel/qwidget.cpp src/widgets/kernel/qwidget_p.h tests/auto/network/socket/platformsocketengine/tst_platformsocketengine.cpp tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp tests/auto/tools/moc/allmocs_baseline_in.json Change-Id: I21a3c34570ae79ea9d30107fae71759d7eac17d9
-rw-r--r--config_help.txt2
-rw-r--r--configure.json1
-rw-r--r--dist/changes-5.14.03
-rw-r--r--examples/embedded/lightmaps/mapzoom.cpp43
-rw-r--r--examples/embedded/lightmaps/mapzoom.h3
-rw-r--r--examples/network/CMakeLists.txt1
-rw-r--r--examples/network/bearermonitor/CMakeLists.txt43
-rw-r--r--examples/network/bearermonitor/bearermonitor.cpp421
-rw-r--r--examples/network/bearermonitor/bearermonitor.h95
-rw-r--r--examples/network/bearermonitor/bearermonitor.pro22
-rw-r--r--examples/network/bearermonitor/bearermonitor_240_320.ui420
-rw-r--r--examples/network/bearermonitor/bearermonitor_640_480.ui386
-rw-r--r--examples/network/bearermonitor/main.cpp69
-rw-r--r--examples/network/bearermonitor/sessionwidget.cpp203
-rw-r--r--examples/network/bearermonitor/sessionwidget.h88
-rw-r--r--examples/network/bearermonitor/sessionwidget.ui307
-rw-r--r--examples/network/fortuneclient/client.cpp48
-rw-r--r--examples/network/fortuneclient/client.h4
-rw-r--r--examples/network/fortuneserver/server.cpp41
-rw-r--r--examples/network/fortuneserver/server.h5
-rw-r--r--examples/network/network-chat/main.cpp39
-rw-r--r--examples/network/network.pro12
-rw-r--r--examples/widgets/doc/src/syntaxhighlighter.qdoc6
-rw-r--r--examples/widgets/widgets/tablet/tabletcanvas.cpp8
-rw-r--r--mkspecs/features/lrelease.prf1
-rw-r--r--mkspecs/features/wasm/default_pre.prf2
-rw-r--r--mkspecs/features/wasm/emcc_ver.prf4
-rw-r--r--qmake/doc/src/qmake-manual.qdoc4
-rw-r--r--qmake/generators/unix/unixmake2.cpp2
-rw-r--r--qmake/generators/win32/winmakefile.cpp14
-rw-r--r--src/3rdparty/md4c/md4c.c596
-rw-r--r--src/3rdparty/md4c/md4c.h19
-rw-r--r--src/3rdparty/md4c/qt_attribution.json6
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtNative.java71
-rw-r--r--src/corelib/codecs/qutfcodec.cpp1
-rw-r--r--src/corelib/global/qnamespace.h2
-rw-r--r--src/corelib/global/qnamespace.qdoc10
-rw-r--r--src/corelib/io/qprocess.cpp33
-rw-r--r--src/corelib/io/qprocess.h19
-rw-r--r--src/corelib/io/qstandardpaths.cpp5
-rw-r--r--src/corelib/io/qurl.cpp2
-rw-r--r--src/corelib/itemmodels/qsortfilterproxymodel.cpp8
-rw-r--r--src/corelib/kernel/qmath.qdoc2
-rw-r--r--src/corelib/kernel/qmetatype.cpp2
-rw-r--r--src/corelib/kernel/qobject.cpp46
-rw-r--r--src/corelib/kernel/qobject_p.h24
-rw-r--r--src/corelib/kernel/qobjectdefs.h2
-rw-r--r--src/corelib/serialization/qcborcommon.cpp4
-rw-r--r--src/corelib/text/qharfbuzz.cpp2
-rw-r--r--src/corelib/text/qstring.cpp6
-rw-r--r--src/corelib/text/qstring.h2
-rw-r--r--src/corelib/text/qstringview.cpp6
-rw-r--r--src/corelib/thread/qmutex.cpp6
-rw-r--r--src/corelib/time/qdatetime.cpp85
-rw-r--r--src/corelib/time/qdatetime.h5
-rw-r--r--src/corelib/tools/qmap.cpp5
-rw-r--r--src/corelib/tools/qmap.h41
-rw-r--r--src/corelib/tools/qvarlengtharray.qdoc2
-rw-r--r--src/gui/.prev_CMakeLists.txt2
-rw-r--r--src/gui/CMakeLists.txt2
-rw-r--r--src/gui/image/qimage.h3
-rw-r--r--src/gui/kernel/qevent.cpp12
-rw-r--r--src/gui/kernel/qevent.h11
-rw-r--r--src/gui/kernel/qguiapplication.cpp13
-rw-r--r--src/gui/painting/qcolor.cpp1
-rw-r--r--src/gui/painting/qicc.cpp116
-rw-r--r--src/gui/rhi/qrhi.cpp132
-rw-r--r--src/gui/rhi/qrhi_p.h13
-rw-r--r--src/gui/rhi/qrhid3d11.cpp15
-rw-r--r--src/gui/rhi/qrhid3d11_p_p.h1
-rw-r--r--src/gui/rhi/qrhigles2.cpp18
-rw-r--r--src/gui/rhi/qrhigles2_p_p.h5
-rw-r--r--src/gui/rhi/qrhimetal.mm17
-rw-r--r--src/gui/rhi/qrhimetal_p_p.h1
-rw-r--r--src/gui/rhi/qrhinull.cpp4
-rw-r--r--src/gui/rhi/qrhivulkan.cpp17
-rw-r--r--src/gui/rhi/qrhivulkan_p_p.h1
-rw-r--r--src/gui/text/qtextdocument.cpp3
-rw-r--r--src/gui/text/text.pri2
-rw-r--r--src/gui/util/qshadergenerator.cpp106
-rw-r--r--src/gui/util/qshadergraph.cpp64
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel.cpp1
-rw-r--r--src/network/access/qhttpnetworkreply.cpp5
-rw-r--r--src/network/access/qhttpnetworkreply_p.h3
-rw-r--r--src/network/access/qhttpthreaddelegate.cpp6
-rw-r--r--src/network/access/qnetworkaccessmanager.cpp23
-rw-r--r--src/network/access/qnetworkaccessmanager.h2
-rw-r--r--src/network/access/qnetworkrequest.cpp6
-rw-r--r--src/network/access/qnetworkrequest.h4
-rw-r--r--src/network/doc/src/network-programming.qdoc25
-rw-r--r--src/network/doc/src/qtnetwork.qdoc1
-rw-r--r--src/network/kernel/qnetconmonitor_win.cpp38
-rw-r--r--src/network/socket/qabstractsocket.cpp7
-rw-r--r--src/network/socket/qlocalsocket.cpp2
-rw-r--r--src/network/socket/qnativesocketengine_win.cpp3
-rw-r--r--src/platformsupport/windowsuiautomation/uiapropertyids_p.h1
-rw-r--r--src/platformsupport/windowsuiautomation/uiaserverinterfaces_p.h17
-rw-r--r--src/platformsupport/windowsuiautomation/uiatypes_p.h7
-rw-r--r--src/plugins/platforms/android/qandroidplatformfiledialoghelper.cpp176
-rw-r--r--src/plugins/platforms/android/qandroidplatformfiledialoghelper.h36
-rw-r--r--src/plugins/platforms/android/qandroidplatformservices.cpp15
-rw-r--r--src/plugins/platforms/cocoa/qcocoabackingstore.mm3
-rw-r--r--src/plugins/platforms/wasm/qwasmeventdispatcher.cpp1
-rw-r--r--src/plugins/platforms/windows/.prev_CMakeLists.txt1
-rw-r--r--src/plugins/platforms/windows/CMakeLists.txt1
-rw-r--r--src/plugins/platforms/windows/qwindowsinputcontext.cpp2
-rw-r--r--src/plugins/platforms/windows/qwindowstheme.cpp5
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp2
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiaexpandcollapseprovider.cpp120
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiaexpandcollapseprovider.h69
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp15
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp2
-rw-r--r--src/plugins/platforms/windows/uiautomation/uiautomation.pri2
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection_xi2.cpp2
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.cpp4
-rw-r--r--src/plugins/sqldrivers/mysql/qsql_mysql.cpp59
-rw-r--r--src/plugins/sqldrivers/odbc/qsql_odbc.cpp76
-rw-r--r--src/plugins/sqldrivers/psql/qsql_psql.cpp48
-rw-r--r--src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp25
-rw-r--r--src/plugins/styles/mac/qmacstyle_mac.mm13
-rw-r--r--src/plugins/styles/windowsvista/qwindowsvistastyle.cpp2
-rw-r--r--src/plugins/styles/windowsvista/qwindowsxpstyle.cpp4
-rw-r--r--src/sql/kernel/qsqldriver_p.h8
-rw-r--r--src/testlib/qtestlog.cpp4
-rw-r--r--src/tools/moc/generator.cpp6
-rw-r--r--src/tools/moc/moc.cpp6
-rw-r--r--src/tools/moc/moc.h1
-rw-r--r--src/widgets/dialogs/qcolordialog.cpp3
-rw-r--r--src/widgets/dialogs/qfiledialog.cpp35
-rw-r--r--src/widgets/dialogs/qwizard.cpp7
-rw-r--r--src/widgets/graphicsview/qgraphicslayout_p.h4
-rw-r--r--src/widgets/graphicsview/qgraphicslayoutstyleinfo.cpp4
-rw-r--r--src/widgets/graphicsview/qgraphicsproxywidget.cpp4
-rw-r--r--src/widgets/graphicsview/qgraphicsview.cpp44
-rw-r--r--src/widgets/graphicsview/qgraphicsview_p.h1
-rw-r--r--src/widgets/graphicsview/qgraphicswidget.cpp2
-rw-r--r--src/widgets/itemviews/qabstractitemview.cpp13
-rw-r--r--src/widgets/itemviews/qitemdelegate.cpp2
-rw-r--r--src/widgets/itemviews/qlistview.cpp7
-rw-r--r--src/widgets/itemviews/qtablewidget.cpp2
-rw-r--r--src/widgets/kernel/qapplication.cpp7
-rw-r--r--src/widgets/kernel/qwidget.cpp11
-rw-r--r--src/widgets/kernel/qwidget_p.h1
-rw-r--r--src/widgets/kernel/qwidgetwindow.cpp37
-rw-r--r--src/widgets/kernel/qwidgetwindow_p.h1
-rw-r--r--src/widgets/styles/qcommonstyle.cpp42
-rw-r--r--src/widgets/styles/qfusionstyle.cpp8
-rw-r--r--src/widgets/styles/qpixmapstyle.cpp4
-rw-r--r--src/widgets/styles/qstyle.cpp2
-rw-r--r--src/widgets/styles/qstyle.h18
-rw-r--r--src/widgets/styles/qstylehelper.cpp6
-rw-r--r--src/widgets/styles/qwindowsstyle.cpp2
-rw-r--r--src/widgets/widgets/qcalendarwidget.cpp4
-rw-r--r--src/widgets/widgets/qcombobox_p.h2
-rw-r--r--src/widgets/widgets/qcommandlinkbutton.cpp8
-rw-r--r--src/widgets/widgets/qeffects.cpp16
-rw-r--r--src/widgets/widgets/qfocusframe.cpp12
-rw-r--r--src/widgets/widgets/qgroupbox.cpp6
-rw-r--r--src/widgets/widgets/qlineedit.cpp2
-rw-r--r--src/widgets/widgets/qmenu.cpp2
-rw-r--r--src/widgets/widgets/qmenubar.cpp2
-rw-r--r--src/widgets/widgets/qtoolbarextension.cpp4
-rw-r--r--src/widgets/widgets/qwidgettextcontrol.cpp2
-rw-r--r--src/xml/dom/qdom.cpp5
-rw-r--r--src/xml/dom/qdomhelpers.cpp6
-rw-r--r--tests/auto/corelib/text/qstring/tst_qstring.cpp6
-rw-r--r--tests/auto/gui/image/qimagereader/tst_qimagereader.cpp38
-rw-r--r--tests/auto/gui/rhi/qrhi/tst_qrhi.cpp95
-rw-r--r--tests/auto/gui/text/qfont/tst_qfont.cpp20
-rw-r--r--tests/auto/gui/util/qshadergenerator/tst_qshadergenerator.cpp193
-rw-r--r--tests/auto/gui/util/qshadergraph/tst_qshadergraph.cpp57
-rw-r--r--tests/auto/network-settings.h16
-rw-r--r--tests/auto/network/socket/platformsocketengine/tst_platformsocketengine.cpp21
-rw-r--r--tests/auto/network/socket/qtcpsocket/BLACKLIST7
-rw-r--r--tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp53
-rw-r--r--tests/auto/tools/moc/allmocs_baseline_in.json73
-rw-r--r--tests/auto/widgets/dialogs/qfilesystemmodel/BLACKLIST4
-rw-r--r--tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp2
-rw-r--r--tests/auto/widgets/kernel/qwidget/hellotr_la.qmbin0 -> 237 bytes
-rw-r--r--tests/auto/widgets/kernel/qwidget/qwidget.qrc1
-rw-r--r--tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp215
-rw-r--r--tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp2
-rw-r--r--tests/libfuzzer/gui/text/qtextdocument/sethtml/main.cpp (renamed from tests/libfuzzer/gui/text/qtextdocument/setHtml/main.cpp)0
-rw-r--r--tests/libfuzzer/gui/text/qtextdocument/sethtml/sethtml.pro (renamed from tests/libfuzzer/gui/text/qtextdocument/setHtml/setHtml.pro)0
-rw-r--r--tests/libfuzzer/gui/text/qtextdocument/setmarkdown/main.cpp (renamed from tests/libfuzzer/gui/text/qtextdocument/setMarkdown/main.cpp)0
-rw-r--r--tests/libfuzzer/gui/text/qtextdocument/setmarkdown/setmarkdown.pro (renamed from tests/libfuzzer/gui/text/qtextdocument/setMarkdown/setMarkdown.pro)0
-rw-r--r--tests/libfuzzer/gui/text/qtextlayout/beginlayout/beginlayout.pro (renamed from tests/libfuzzer/gui/text/qtextlayout/beginLayout/beginLayout.pro)0
-rw-r--r--tests/libfuzzer/gui/text/qtextlayout/beginlayout/main.cpp (renamed from tests/libfuzzer/gui/text/qtextlayout/beginLayout/main.cpp)0
-rw-r--r--tests/manual/rhi/hellominimalcrossgfxtriangle/window.cpp2
189 files changed, 2667 insertions, 3203 deletions
diff --git a/config_help.txt b/config_help.txt
index 5d116ce780..3d3ddb803c 100644
--- a/config_help.txt
+++ b/config_help.txt
@@ -164,8 +164,6 @@ Build options:
-reduce-exports ...... Reduce amount of exported symbols [auto]
-reduce-relocations .. Reduce amount of relocations [auto] (Unix only)
- -relocatable ......... Enable the Qt installation to be relocated [auto]
-
-plugin-manifests .... Embed manifests into plugins [no] (Windows only)
-static-runtime ...... With -static, use static runtime [no] (Windows only)
diff --git a/configure.json b/configure.json
index d11fa18bf1..cf123602c2 100644
--- a/configure.json
+++ b/configure.json
@@ -1407,6 +1407,7 @@
},
"relocatable": {
"label": "Relocatable",
+ "purpose": "Enable the Qt installation to be relocated.",
"autoDetect": "features.shared",
"condition": "features.dlopen || config.win32 || !features.shared",
"output": [ "privateFeature" ]
diff --git a/dist/changes-5.14.0 b/dist/changes-5.14.0
index 77cbb70928..9069663715 100644
--- a/dist/changes-5.14.0
+++ b/dist/changes-5.14.0
@@ -476,6 +476,9 @@ information about a particular change.
- MinGW:
* [QTBUG-4155] Added a suffix to debug mode pkgconfig files.
+ * MinGW does not built with -debug-and-release mode anymore.
+ Instead, the binaries are built with -release -force-debug-info
+ -separate-debug-info.
- macOS:
* The drawableSize of Metal layers is no longer updated automatically on
diff --git a/examples/embedded/lightmaps/mapzoom.cpp b/examples/embedded/lightmaps/mapzoom.cpp
index d82b9ad473..781d4f27e3 100644
--- a/examples/embedded/lightmaps/mapzoom.cpp
+++ b/examples/embedded/lightmaps/mapzoom.cpp
@@ -81,52 +81,9 @@ MapZoom::MapZoom()
menu->addAction(nightModeAction);
menu->addAction(osmAction);
- QNetworkConfigurationManager manager;
- if (manager.capabilities() & QNetworkConfigurationManager::NetworkSessionRequired) {
- // Get saved network configuration
- QSettings settings(QSettings::UserScope, QLatin1String("QtProject"));
- settings.beginGroup(QLatin1String("QtNetwork"));
- const QString id =
- settings.value(QLatin1String("DefaultNetworkConfiguration")).toString();
- settings.endGroup();
-
- // If the saved network configuration is not currently discovered use the system
- // default
- QNetworkConfiguration config = manager.configurationFromIdentifier(id);
- if ((config.state() & QNetworkConfiguration::Discovered) !=
- QNetworkConfiguration::Discovered) {
- config = manager.defaultConfiguration();
- }
-
- networkSession = new QNetworkSession(config, this);
- connect(networkSession, SIGNAL(opened()), this, SLOT(sessionOpened()));
-
- networkSession->open();
- } else {
- networkSession = 0;
- }
-
setWindowTitle(tr("Light Maps"));
}
-void MapZoom::sessionOpened()
-{
- // Save the used configuration
- QNetworkConfiguration config = networkSession->configuration();
- QString id;
- if (config.type() == QNetworkConfiguration::UserChoice) {
- id = networkSession->sessionProperty(
- QLatin1String("UserChoiceConfiguration")).toString();
- } else {
- id = config.identifier();
- }
-
- QSettings settings(QSettings::UserScope, QLatin1String("QtProject"));
- settings.beginGroup(QLatin1String("QtNetwork"));
- settings.setValue(QLatin1String("DefaultNetworkConfiguration"), id);
- settings.endGroup();
-}
-
void MapZoom::chooseOslo()
{
map->setCenter(59.9138204, 10.7387413);
diff --git a/examples/embedded/lightmaps/mapzoom.h b/examples/embedded/lightmaps/mapzoom.h
index 30f2e63138..3844eca718 100644
--- a/examples/embedded/lightmaps/mapzoom.h
+++ b/examples/embedded/lightmaps/mapzoom.h
@@ -53,7 +53,6 @@
#include <QMainWindow>
-class QNetworkSession;
class LightMaps;
class MapZoom : public QMainWindow
@@ -64,7 +63,6 @@ public:
MapZoom();
private slots:
- void sessionOpened();
void chooseOslo();
void chooseBerlin();
void chooseJakarta();
@@ -72,7 +70,6 @@ private slots:
private:
LightMaps *map;
- QNetworkSession *networkSession;
};
#endif \ No newline at end of file
diff --git a/examples/network/CMakeLists.txt b/examples/network/CMakeLists.txt
index af1f923dc6..919310df9a 100644
--- a/examples/network/CMakeLists.txt
+++ b/examples/network/CMakeLists.txt
@@ -20,7 +20,6 @@ if(TARGET Qt::Widgets)
add_subdirectory(multicastsender)
if(QT_FEATURE_bearermanagement)
- add_subdirectory(bearermonitor)
add_subdirectory(fortuneclient)
add_subdirectory(fortuneserver)
diff --git a/examples/network/bearermonitor/CMakeLists.txt b/examples/network/bearermonitor/CMakeLists.txt
deleted file mode 100644
index 4e8bfca813..0000000000
--- a/examples/network/bearermonitor/CMakeLists.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-# Generated from bearermonitor.pro.
-
-cmake_minimum_required(VERSION 3.14)
-project(bearermonitor LANGUAGES CXX)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTORCC ON)
-set(CMAKE_AUTOUIC ON)
-
-set(INSTALL_EXAMPLEDIR "examples/network/bearermonitor")
-
-find_package(Qt6 COMPONENTS Core)
-find_package(Qt6 COMPONENTS Gui)
-find_package(Qt6 COMPONENTS Network)
-find_package(Qt6 COMPONENTS Widgets)
-
-add_executable(bearermonitor
- bearermonitor.cpp bearermonitor.h
- bearermonitor_240_320.ui
- bearermonitor_640_480.ui
- main.cpp
- sessionwidget.cpp sessionwidget.h sessionwidget.ui
-)
-target_link_libraries(bearermonitor PUBLIC
- Qt::Core
- Qt::Gui
- Qt::Network
- Qt::Widgets
-)
-
-if(WIN32)
- target_link_libraries(bearermonitor PUBLIC
- ws2_32
- )
-endif()
-
-install(TARGETS bearermonitor
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
-)
diff --git a/examples/network/bearermonitor/bearermonitor.cpp b/examples/network/bearermonitor/bearermonitor.cpp
deleted file mode 100644
index 322224a902..0000000000
--- a/examples/network/bearermonitor/bearermonitor.cpp
+++ /dev/null
@@ -1,421 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, you may use this file under the terms of the BSD license
-** as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of The Qt Company Ltd nor the names of its
-** contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "bearermonitor.h"
-#include "sessionwidget.h"
-
-#include <QtCore/QDebug>
-
-#ifdef Q_OS_WIN
-#include <winsock2.h>
-#undef interface
-
-#ifndef NS_NLA
-#define NS_NLA 15
-#endif
-#endif
-
-BearerMonitor::BearerMonitor(QWidget *parent)
-: QWidget(parent)
-{
- setupUi(this);
- delete tabWidget->currentWidget();
- sessionGroup->hide();
- updateConfigurations();
- onlineStateChanged(!manager.allConfigurations(QNetworkConfiguration::Active).isEmpty());
- QNetworkConfiguration defaultConfiguration = manager.defaultConfiguration();
- for (int i = 0; i < treeWidget->topLevelItemCount(); ++i) {
- QTreeWidgetItem *item = treeWidget->topLevelItem(i);
-
- if (item->data(0, Qt::UserRole).toString() == defaultConfiguration.identifier()) {
- treeWidget->setCurrentItem(item);
- showConfigurationFor(item);
- break;
- }
- }
- connect(&manager, &QNetworkConfigurationManager::onlineStateChanged,
- this, &BearerMonitor::onlineStateChanged);
- connect(&manager, &QNetworkConfigurationManager::configurationAdded,
- this, [this](const QNetworkConfiguration &config) { configurationAdded(config); });
- connect(&manager, &QNetworkConfigurationManager::configurationRemoved,
- this, &BearerMonitor::configurationRemoved);
- connect(&manager, &QNetworkConfigurationManager::configurationChanged,
- this, &BearerMonitor::configurationChanged);
- connect(&manager, &QNetworkConfigurationManager::updateCompleted,
- this, &BearerMonitor::updateConfigurations);
-
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
- connect(registerButton, &QPushButton::clicked,
- this, &BearerMonitor::registerNetwork);
- connect(unregisterButton, &QPushButton::clicked,
- this, &BearerMonitor::unregisterNetwork);
-#else // Q_OS_WIN && !Q_OS_WINRT
- nlaGroup->hide();
-#endif
-
- connect(treeWidget, &QTreeWidget::itemActivated,
- this, &BearerMonitor::createSessionFor);
- connect(treeWidget, &QTreeWidget::currentItemChanged,
- this, &BearerMonitor::showConfigurationFor);
-
- connect(newSessionButton, &QPushButton::clicked,
- this, &BearerMonitor::createNewSession);
- connect(deleteSessionButton, &QPushButton::clicked,
- this, &BearerMonitor::deleteSession);
- connect(scanButton, &QPushButton::clicked,
- this, &BearerMonitor::performScan);
-
- // Just in case update all configurations so that all
- // configurations are up to date.
- manager.updateConfigurations();
-}
-
-BearerMonitor::~BearerMonitor()
-{
-}
-
-static void updateItem(QTreeWidgetItem *item, const QNetworkConfiguration &config)
-{
- item->setText(0, config.name());
- item->setData(0, Qt::UserRole, config.identifier());
-
- QFont font = item->font(1);
- font.setBold(config.state().testFlag(QNetworkConfiguration::Active));
- item->setFont(0, font);
-}
-
-void BearerMonitor::configurationAdded(const QNetworkConfiguration &config, QTreeWidgetItem *parent)
-{
- if (!config.isValid())
- return;
-
- QTreeWidgetItem *item = new QTreeWidgetItem;
- updateItem(item, config);
-
- if (parent)
- parent->addChild(item);
- else
- treeWidget->addTopLevelItem(item);
-
- if (config.type() == QNetworkConfiguration::ServiceNetwork) {
- const QList<QNetworkConfiguration> children = config.children();
- for (const QNetworkConfiguration &child : children)
- configurationAdded(child, item);
- }
-}
-
-void BearerMonitor::configurationRemoved(const QNetworkConfiguration &config)
-{
- for (int i = 0; i < treeWidget->topLevelItemCount(); ++i) {
- QTreeWidgetItem *item = treeWidget->topLevelItem(i);
-
- if (item->data(0, Qt::UserRole).toString() == config.identifier()) {
- delete item;
- break;
- }
- }
-}
-
-void BearerMonitor::configurationChanged(const QNetworkConfiguration &config)
-{
- for (int i = 0; i < treeWidget->topLevelItemCount(); ++i) {
- QTreeWidgetItem *item = treeWidget->topLevelItem(i);
-
- if (item->data(0, Qt::UserRole).toString() == config.identifier()) {
- updateItem(item, config);
-
- if (config.type() == QNetworkConfiguration::ServiceNetwork)
- updateSnapConfiguration(item, config);
-
- if (item == treeWidget->currentItem())
- showConfigurationFor(item);
-
- break;
- }
- }
-}
-
-void BearerMonitor::updateSnapConfiguration(QTreeWidgetItem *parent, const QNetworkConfiguration &snap)
-{
- QMap<QString, QTreeWidgetItem *> itemMap;
- const QList<QTreeWidgetItem *> children = parent->takeChildren();
- for (QTreeWidgetItem *item : children)
- itemMap.insert(item->data(0, Qt::UserRole).toString(), item);
-
- QList<QNetworkConfiguration> allConfigurations = snap.children();
-
- while (!allConfigurations.isEmpty()) {
- QNetworkConfiguration config = allConfigurations.takeFirst();
-
- QTreeWidgetItem *item = itemMap.take(config.identifier());
- if (item) {
- updateItem(item, config);
-
- parent->addChild(item);
-
- if (config.type() == QNetworkConfiguration::ServiceNetwork)
- updateSnapConfiguration(item, config);
- } else {
- configurationAdded(config, parent);
- }
- }
-
- qDeleteAll(itemMap);
-}
-
-void BearerMonitor::updateConfigurations()
-{
- progressBar->hide();
- scanButton->show();
-
- // Just in case update online state, on Symbian platform
- // WLAN scan needs to be triggered initially to have their true state.
- onlineStateChanged(manager.isOnline());
-
- QList<QTreeWidgetItem *> items = treeWidget->findItems(QLatin1String("*"), Qt::MatchWildcard);
- QMap<QString, QTreeWidgetItem *> itemMap;
- while (!items.isEmpty()) {
- QTreeWidgetItem *item = items.takeFirst();
- itemMap.insert(item->data(0, Qt::UserRole).toString(), item);
- }
-
- QNetworkConfiguration defaultConfiguration = manager.defaultConfiguration();
- QTreeWidgetItem *defaultItem = itemMap.take(defaultConfiguration.identifier());
-
- if (defaultItem) {
- updateItem(defaultItem, defaultConfiguration);
-
- if (defaultConfiguration.type() == QNetworkConfiguration::ServiceNetwork)
- updateSnapConfiguration(defaultItem, defaultConfiguration);
- } else {
- configurationAdded(defaultConfiguration);
- }
-
- QList<QNetworkConfiguration> allConfigurations = manager.allConfigurations();
-
- while (!allConfigurations.isEmpty()) {
- QNetworkConfiguration config = allConfigurations.takeFirst();
-
- if (config.identifier() == defaultConfiguration.identifier())
- continue;
-
- QTreeWidgetItem *item = itemMap.take(config.identifier());
- if (item) {
- updateItem(item, config);
-
- if (config.type() == QNetworkConfiguration::ServiceNetwork)
- updateSnapConfiguration(item, config);
- } else {
- configurationAdded(config);
- }
- }
-
- qDeleteAll(itemMap);
-}
-
-void BearerMonitor::onlineStateChanged(bool isOnline)
-{
- if (isOnline)
- onlineState->setText(tr("Online"));
- else
- onlineState->setText(tr("Offline"));
-}
-
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
-void BearerMonitor::registerNetwork()
-{
- QTreeWidgetItem *item = treeWidget->currentItem();
- if (!item) return;
-
- QNetworkConfiguration configuration =
- manager.configurationFromIdentifier(item->data(0, Qt::UserRole).toString());
-
- const QString name = configuration.name();
-
- qDebug() << "Registering" << name << "with system";
-
- WSAQUERYSET networkInfo;
- memset(&networkInfo, 0, sizeof(networkInfo));
- networkInfo.dwSize = sizeof(networkInfo);
- networkInfo.lpszServiceInstanceName = (LPWSTR)name.utf16();
- networkInfo.dwNameSpace = NS_NLA;
-
- if (WSASetService(&networkInfo, RNRSERVICE_REGISTER, 0) == SOCKET_ERROR)
- qDebug() << "WSASetService(RNRSERVICE_REGISTER) returned" << WSAGetLastError();
-}
-
-void BearerMonitor::unregisterNetwork()
-{
- QTreeWidgetItem *item = treeWidget->currentItem();
- if (!item) return;
-
- QNetworkConfiguration configuration =
- manager.configurationFromIdentifier(item->data(0, Qt::UserRole).toString());
-
- const QString name = configuration.name();
-
- qDebug() << "Unregistering" << name << "with system";
-
- WSAQUERYSET networkInfo;
- memset(&networkInfo, 0, sizeof(networkInfo));
- networkInfo.dwSize = sizeof(networkInfo);
- networkInfo.lpszServiceInstanceName = (LPWSTR)name.utf16();
- networkInfo.dwNameSpace = NS_NLA;
-
- if (WSASetService(&networkInfo, RNRSERVICE_DELETE, 0) == SOCKET_ERROR)
- qDebug() << "WSASetService(RNRSERVICE_DELETE) returned" << WSAGetLastError();
-}
-#endif // Q_OS_WIN && !Q_OS_WINRT
-
-void BearerMonitor::showConfigurationFor(QTreeWidgetItem *item)
-{
- QString identifier;
-
- if (item)
- identifier = item->data(0, Qt::UserRole).toString();
-
- QNetworkConfiguration conf = manager.configurationFromIdentifier(identifier);
-
- switch (conf.state()) {
- case QNetworkConfiguration::Active:
- configurationState->setText(tr("Active"));
- break;
- case QNetworkConfiguration::Discovered:
- configurationState->setText(tr("Discovered"));
- break;
- case QNetworkConfiguration::Defined:
- configurationState->setText(tr("Defined"));
- break;
- case QNetworkConfiguration::Undefined:
- configurationState->setText(tr("Undefined"));
- break;
- }
-
- switch (conf.type()) {
- case QNetworkConfiguration::InternetAccessPoint:
- configurationType->setText(tr("Internet Access Point"));
- break;
- case QNetworkConfiguration::ServiceNetwork:
- configurationType->setText(tr("Service Network"));
- break;
- case QNetworkConfiguration::UserChoice:
- configurationType->setText(tr("User Choice"));
- break;
- case QNetworkConfiguration::Invalid:
- configurationType->setText(tr("Invalid"));
- break;
- }
-
- switch (conf.purpose()) {
- case QNetworkConfiguration::UnknownPurpose:
- configurationPurpose->setText(tr("Unknown"));
- break;
- case QNetworkConfiguration::PublicPurpose:
- configurationPurpose->setText(tr("Public"));
- break;
- case QNetworkConfiguration::PrivatePurpose:
- configurationPurpose->setText(tr("Private"));
- break;
- case QNetworkConfiguration::ServiceSpecificPurpose:
- configurationPurpose->setText(tr("Service Specific"));
- break;
- }
-
- configurationIdentifier->setText(conf.identifier());
-
- configurationRoaming->setText(conf.isRoamingAvailable() ? tr("Available") : tr("Not available"));
-
- configurationChildren->setText(QString::number(conf.children().count()));
-
- configurationName->setText(conf.name());
-}
-
-void BearerMonitor::createSessionFor(QTreeWidgetItem *item)
-{
- const QString identifier = item->data(0, Qt::UserRole).toString();
-
- QNetworkConfiguration conf = manager.configurationFromIdentifier(identifier);
-
- SessionWidget *session = new SessionWidget(conf);
-
- tabWidget->addTab(session, conf.name());
-
- sessionGroup->show();
-
- sessionWidgets.append(session);
-}
-
-void BearerMonitor::createNewSession()
-{
- QTreeWidgetItem *item = treeWidget->currentItem();
- if (!item) return;
-
- createSessionFor(item);
-}
-
-void BearerMonitor::deleteSession()
-{
- SessionWidget *session = qobject_cast<SessionWidget *>(tabWidget->currentWidget());
- if (session) {
- sessionWidgets.removeAll(session);
-
- delete session;
-
- if (tabWidget->count() == 0)
- sessionGroup->hide();
- }
-}
-
-void BearerMonitor::performScan()
-{
- scanButton->hide();
- progressBar->show();
- manager.updateConfigurations();
-}
diff --git a/examples/network/bearermonitor/bearermonitor.h b/examples/network/bearermonitor/bearermonitor.h
deleted file mode 100644
index 79b8d876ec..0000000000
--- a/examples/network/bearermonitor/bearermonitor.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, you may use this file under the terms of the BSD license
-** as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of The Qt Company Ltd nor the names of its
-** contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef BEARERMONITOR_H
-#define BEARERMONITOR_H
-
-#include <QNetworkConfigurationManager>
-#include "ui_bearermonitor_640_480.h"
-
-QT_USE_NAMESPACE
-
-class SessionWidget;
-
-class BearerMonitor : public QWidget, public Ui_BearerMonitor
-{
- Q_OBJECT
-
-public:
- BearerMonitor(QWidget *parent = nullptr);
- ~BearerMonitor();
-
-private slots:
- void configurationAdded(const QNetworkConfiguration &config, QTreeWidgetItem *parent = nullptr);
- void configurationRemoved(const QNetworkConfiguration &config);
- void configurationChanged(const QNetworkConfiguration &config);
- void updateSnapConfiguration(QTreeWidgetItem *parent, const QNetworkConfiguration &snap);
- void updateConfigurations();
-
- void onlineStateChanged(bool isOnline);
-
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
- void registerNetwork();
- void unregisterNetwork();
-#endif // Q_OS_WIN && !Q_OS_WINRT
-
- void showConfigurationFor(QTreeWidgetItem *item);
-
- void createSessionFor(QTreeWidgetItem *item);
- void createNewSession();
- void deleteSession();
- void performScan();
-
-private:
- QNetworkConfigurationManager manager;
- QVector<SessionWidget *> sessionWidgets;
-};
-
-#endif //BEARERMONITOR_H
diff --git a/examples/network/bearermonitor/bearermonitor.pro b/examples/network/bearermonitor/bearermonitor.pro
deleted file mode 100644
index 16ac41298a..0000000000
--- a/examples/network/bearermonitor/bearermonitor.pro
+++ /dev/null
@@ -1,22 +0,0 @@
-TARGET = bearermonitor
-QT = core gui network widgets
-requires(qtConfig(treeview))
-
-HEADERS = sessionwidget.h \
- bearermonitor.h
-
-SOURCES = main.cpp \
- bearermonitor.cpp \
- sessionwidget.cpp
-
-FORMS = bearermonitor_240_320.ui \
- bearermonitor_640_480.ui \
- sessionwidget.ui
-
-win32: QMAKE_USE += ws2_32
-
-CONFIG += console
-
-# install
-target.path = $$[QT_INSTALL_EXAMPLES]/network/bearermonitor
-INSTALLS += target
diff --git a/examples/network/bearermonitor/bearermonitor_240_320.ui b/examples/network/bearermonitor/bearermonitor_240_320.ui
deleted file mode 100644
index 93cfc5e0e3..0000000000
--- a/examples/network/bearermonitor/bearermonitor_240_320.ui
+++ /dev/null
@@ -1,420 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>BearerMonitor</class>
- <widget class="QWidget" name="BearerMonitor">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>240</width>
- <height>320</height>
- </rect>
- </property>
- <property name="windowTitle">
- <string>BearerMonitor</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_5">
- <item>
- <widget class="QScrollArea" name="scrollArea">
- <property name="frameShape">
- <enum>QFrame::NoFrame</enum>
- </property>
- <property name="frameShadow">
- <enum>QFrame::Plain</enum>
- </property>
- <property name="widgetResizable">
- <bool>true</bool>
- </property>
- <widget class="QWidget" name="scrollAreaWidgetContents">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>-274</y>
- <width>206</width>
- <height>576</height>
- </rect>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_2">
- <item>
- <widget class="QGroupBox" name="systemState">
- <property name="title">
- <string>System State</string>
- </property>
- <property name="flat">
- <bool>true</bool>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_4">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item>
- <layout class="QHBoxLayout" name="onlineStateLayout">
- <item>
- <widget class="QLabel" name="onlineStateLabel">
- <property name="text">
- <string>Online State:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="onlineState">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="groupBox">
- <property name="title">
- <string>Configurations</string>
- </property>
- <property name="flat">
- <bool>true</bool>
- </property>
- <layout class="QHBoxLayout" name="horizontalLayout_9">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item>
- <layout class="QVBoxLayout" name="verticalLayout">
- <item>
- <layout class="QHBoxLayout" name="configurationNameLayout">
- <item>
- <widget class="QLabel" name="configurationNameLabel">
- <property name="text">
- <string>Name:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="configurationName">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="configurationStateLayout">
- <item>
- <widget class="QLabel" name="configurationStateLabel">
- <property name="text">
- <string>State:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="configurationState">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="configurationTypeLayout">
- <item>
- <widget class="QLabel" name="configurationTypeLabel">
- <property name="text">
- <string>Type:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="configurationType">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Invalid</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="configurationPurposeLayout">
- <item>
- <widget class="QLabel" name="configurationPurposeLabel">
- <property name="text">
- <string>Purpose:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="configurationPurpose">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Unknown</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="configurationIdentifierLayout">
- <item>
- <widget class="QLabel" name="configurationIdentifierLabel">
- <property name="text">
- <string>Identifier:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="configurationIdentifier">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="configurationRoamingLayout">
- <item>
- <widget class="QLabel" name="configurationRoamingLabel">
- <property name="text">
- <string>Roaming:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="configurationRoaming">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="configurationChildrenLayout">
- <item>
- <widget class="QLabel" name="configurationChildrenLabel">
- <property name="text">
- <string>Children:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="configurationChildren">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <widget class="QGroupBox" name="nlaGroup">
- <property name="title">
- <string>Network Location Awareness</string>
- </property>
- <layout class="QHBoxLayout" name="horizontalLayout">
- <item>
- <widget class="QPushButton" name="registerButton">
- <property name="text">
- <string>Register</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="unregisterButton">
- <property name="text">
- <string>Unregister</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="newSessionButton">
- <property name="text">
- <string>New Session</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="deleteSessionButton">
- <property name="text">
- <string>Delete Session</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="scanButton">
- <property name="text">
- <string>Scan</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QProgressBar" name="progressBar">
- <property name="maximum">
- <number>0</number>
- </property>
- <property name="value">
- <number>-1</number>
- </property>
- <property name="textVisible">
- <bool>false</bool>
- </property>
- <property name="invertedAppearance">
- <bool>false</bool>
- </property>
- <property name="format">
- <string>%p%</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QTreeWidget" name="treeWidget">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="verticalScrollBarPolicy">
- <enum>Qt::ScrollBarAlwaysOff</enum>
- </property>
- <attribute name="headerVisible">
- <bool>false</bool>
- </attribute>
- <column>
- <property name="text">
- <string>1</string>
- </property>
- </column>
- </widget>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="sessionGroup">
- <property name="title">
- <string>Sessions</string>
- </property>
- <property name="flat">
- <bool>true</bool>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_3">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item>
- <widget class="QTabWidget" name="tabWidget">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="currentIndex">
- <number>0</number>
- </property>
- <widget class="QWidget" name="tab">
- <attribute name="title">
- <string>Session 1</string>
- </attribute>
- </widget>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- </layout>
- </widget>
- </widget>
- </item>
- </layout>
- </widget>
- <resources/>
- <connections/>
-</ui>
diff --git a/examples/network/bearermonitor/bearermonitor_640_480.ui b/examples/network/bearermonitor/bearermonitor_640_480.ui
deleted file mode 100644
index 52866bc9cd..0000000000
--- a/examples/network/bearermonitor/bearermonitor_640_480.ui
+++ /dev/null
@@ -1,386 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>BearerMonitor</class>
- <widget class="QWidget" name="BearerMonitor">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>640</width>
- <height>515</height>
- </rect>
- </property>
- <property name="windowTitle">
- <string>BearerMonitor</string>
- </property>
- <layout class="QGridLayout" name="gridLayout">
- <item row="0" column="0">
- <widget class="QGroupBox" name="systemState">
- <property name="title">
- <string>System State</string>
- </property>
- <property name="flat">
- <bool>true</bool>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_4">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item>
- <layout class="QHBoxLayout" name="onlineStateLayout">
- <item>
- <widget class="QLabel" name="onlineStateLabel">
- <property name="text">
- <string>Online State:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="onlineState">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QGroupBox" name="groupBox">
- <property name="title">
- <string>Configurations</string>
- </property>
- <property name="flat">
- <bool>true</bool>
- </property>
- <layout class="QHBoxLayout" name="horizontalLayout_9">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item>
- <widget class="QTreeWidget" name="treeWidget">
- <attribute name="headerVisible">
- <bool>false</bool>
- </attribute>
- <column>
- <property name="text">
- <string>1</string>
- </property>
- </column>
- </widget>
- </item>
- <item>
- <layout class="QVBoxLayout" name="verticalLayout">
- <item>
- <layout class="QHBoxLayout" name="configurationNameLayout">
- <item>
- <widget class="QLabel" name="configurationNameLabel">
- <property name="text">
- <string>Name:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="configurationName">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="configurationStateLayout">
- <item>
- <widget class="QLabel" name="configurationStateLabel">
- <property name="text">
- <string>State:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="configurationState">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="configurationTypeLayout">
- <item>
- <widget class="QLabel" name="configurationTypeLabel">
- <property name="text">
- <string>Type:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="configurationType">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Invalid</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="configurationPurposeLayout">
- <item>
- <widget class="QLabel" name="configurationPurposeLabel">
- <property name="text">
- <string>Purpose:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="configurationPurpose">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Unknown</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="configurationIdentifierLayout">
- <item>
- <widget class="QLabel" name="configurationIdentifierLabel">
- <property name="text">
- <string>Identifier:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="configurationIdentifier">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="configurationRoamingLayout">
- <item>
- <widget class="QLabel" name="configurationRoamingLabel">
- <property name="text">
- <string>Roaming:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="configurationRoaming">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="configurationChildrenLayout">
- <item>
- <widget class="QLabel" name="configurationChildrenLabel">
- <property name="text">
- <string>Children:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="configurationChildren">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <widget class="QGroupBox" name="nlaGroup">
- <property name="title">
- <string>Network Location Awareness</string>
- </property>
- <layout class="QHBoxLayout" name="horizontalLayout">
- <item>
- <widget class="QPushButton" name="registerButton">
- <property name="text">
- <string>Register</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="unregisterButton">
- <property name="text">
- <string>Unregister</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="newSessionButton">
- <property name="text">
- <string>New Session</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="deleteSessionButton">
- <property name="text">
- <string>Delete Session</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="scanButton">
- <property name="text">
- <string>Scan</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QProgressBar" name="progressBar">
- <property name="maximum">
- <number>0</number>
- </property>
- <property name="value">
- <number>-1</number>
- </property>
- <property name="textVisible">
- <bool>false</bool>
- </property>
- <property name="invertedAppearance">
- <bool>false</bool>
- </property>
- <property name="format">
- <string>%p%</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QGroupBox" name="sessionGroup">
- <property name="title">
- <string>Sessions</string>
- </property>
- <property name="flat">
- <bool>true</bool>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_3">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item>
- <widget class="QTabWidget" name="tabWidget">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="currentIndex">
- <number>0</number>
- </property>
- <widget class="QWidget" name="tab">
- <attribute name="title">
- <string>Session 1</string>
- </attribute>
- </widget>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- </layout>
- </widget>
- <resources/>
- <connections/>
-</ui>
diff --git a/examples/network/bearermonitor/main.cpp b/examples/network/bearermonitor/main.cpp
deleted file mode 100644
index 3c2525012d..0000000000
--- a/examples/network/bearermonitor/main.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, you may use this file under the terms of the BSD license
-** as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of The Qt Company Ltd nor the names of its
-** contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QApplication>
-#include <QMainWindow>
-
-#include "bearermonitor.h"
-
-int main(int argc, char *argv[])
-{
- QApplication app(argc, argv);
-
- QMainWindow mainWindow;
-
- BearerMonitor monitor;
-
- mainWindow.setCentralWidget(&monitor);
- mainWindow.show();
-
- return app.exec();
-}
-
diff --git a/examples/network/bearermonitor/sessionwidget.cpp b/examples/network/bearermonitor/sessionwidget.cpp
deleted file mode 100644
index 0fd5d4f67f..0000000000
--- a/examples/network/bearermonitor/sessionwidget.cpp
+++ /dev/null
@@ -1,203 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, you may use this file under the terms of the BSD license
-** as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of The Qt Company Ltd nor the names of its
-** contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "sessionwidget.h"
-#include <QNetworkConfigurationManager>
-
-SessionWidget::SessionWidget(const QNetworkConfiguration &config, QWidget *parent)
-: QWidget(parent)
-{
- setupUi(this);
-
-#ifdef QT_NO_NETWORKINTERFACE
- interfaceName->setVisible(false);
- interfaceNameLabel->setVisible(false);
- interfaceGuid->setVisible(false);
- interfaceGuidLabel->setVisible(false);
-#endif
-
- session = new QNetworkSession(config, this);
-
- connect(session, &QNetworkSession::stateChanged,
- this, &SessionWidget::updateSession);
- connect(session, QOverload<QNetworkSession::SessionError>::of(&QNetworkSession::error),
- this, &SessionWidget::updateSessionError);
-
- updateSession();
-
- sessionId->setText(QString("0x%1").arg(qulonglong(session), 8, 16, QChar('0')));
-
- configuration->setText(session->configuration().name());
-
- connect(openSessionButton, &QPushButton::clicked,
- this, &SessionWidget::openSession);
- connect(openSyncSessionButton, &QPushButton::clicked,
- this, &SessionWidget::openSyncSession);
- connect(closeSessionButton, &QPushButton::clicked,
- this, &SessionWidget::closeSession);
- connect(stopSessionButton, &QPushButton::clicked,
- this, &SessionWidget::stopSession);
-}
-
-SessionWidget::~SessionWidget()
-{
- delete session;
-}
-
-void SessionWidget::timerEvent(QTimerEvent *e)
-{
- if (e->timerId() == statsTimer) {
- rxData->setText(QString::number(session->bytesReceived()));
- txData->setText(QString::number(session->bytesWritten()));
- activeTime->setText(QString::number(session->activeTime()));
- }
-}
-
-void SessionWidget::updateSession()
-{
- updateSessionState(session->state());
-
- if (session->state() == QNetworkSession::Connected)
- statsTimer = startTimer(1000);
- else if (statsTimer != -1)
- killTimer(statsTimer);
-
- if (session->configuration().type() == QNetworkConfiguration::InternetAccessPoint)
- bearer->setText(session->configuration().bearerTypeName());
- else {
- QNetworkConfigurationManager mgr;
- QNetworkConfiguration c = mgr.configurationFromIdentifier(session->sessionProperty("ActiveConfiguration").toString());
- bearer->setText(c.bearerTypeName());
- }
-
-#ifndef QT_NO_NETWORKINTERFACE
- interfaceName->setText(session->interface().humanReadableName());
- interfaceGuid->setText(session->interface().name());
-#endif
-}
-
-void SessionWidget::openSession()
-{
- clearError();
- session->open();
- updateSession();
-}
-
-void SessionWidget::openSyncSession()
-{
- clearError();
- session->open();
- session->waitForOpened();
- updateSession();
-}
-
-void SessionWidget::closeSession()
-{
- clearError();
- session->close();
- updateSession();
-}
-
-void SessionWidget::stopSession()
-{
- clearError();
- session->stop();
- updateSession();
-}
-
-void SessionWidget::updateSessionState(QNetworkSession::State state)
-{
- QString s = tr("%1 (%2)");
-
- switch (state) {
- case QNetworkSession::Invalid:
- s = s.arg(tr("Invalid"));
- break;
- case QNetworkSession::NotAvailable:
- s = s.arg(tr("Not Available"));
- break;
- case QNetworkSession::Connecting:
- s = s.arg(tr("Connecting"));
- break;
- case QNetworkSession::Connected:
- s = s.arg(tr("Connected"));
- break;
- case QNetworkSession::Closing:
- s = s.arg(tr("Closing"));
- break;
- case QNetworkSession::Disconnected:
- s = s.arg(tr("Disconnected"));
- break;
- case QNetworkSession::Roaming:
- s = s.arg(tr("Roaming"));
- break;
- default:
- s = s.arg(tr("Unknown"));
- }
-
- if (session->isOpen())
- s = s.arg(tr("Open"));
- else
- s = s.arg(tr("Closed"));
-
- sessionState->setText(s);
-}
-
-void SessionWidget::updateSessionError(QNetworkSession::SessionError error)
-{
- lastError->setText(QString::number(error));
- errorString->setText(session->errorString());
-}
-
-void SessionWidget::clearError()
-{
- lastError->clear();
- errorString->clear();
-}
diff --git a/examples/network/bearermonitor/sessionwidget.h b/examples/network/bearermonitor/sessionwidget.h
deleted file mode 100644
index 6b2da2c1c1..0000000000
--- a/examples/network/bearermonitor/sessionwidget.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, you may use this file under the terms of the BSD license
-** as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of The Qt Company Ltd nor the names of its
-** contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef SESSIONWIDGET_H
-#define SESSIONWIDGET_H
-
-#include <QNetworkSession>
-
-#include "ui_sessionwidget.h"
-
-QT_USE_NAMESPACE
-
-class SessionWidget : public QWidget, public Ui_SessionWidget
-{
- Q_OBJECT
-
-public:
- explicit SessionWidget(const QNetworkConfiguration &config, QWidget *parent = nullptr);
- ~SessionWidget();
-
- void timerEvent(QTimerEvent *e) override;
-
-private:
- void updateSessionState(QNetworkSession::State state);
- void clearError();
-
-private Q_SLOTS:
- void openSession();
- void openSyncSession();
- void closeSession();
- void stopSession();
- void updateSession();
- void updateSessionError(QNetworkSession::SessionError error);
-
-private:
- QNetworkSession *session = nullptr;
- int statsTimer = -1;
-};
-
-#endif
-
diff --git a/examples/network/bearermonitor/sessionwidget.ui b/examples/network/bearermonitor/sessionwidget.ui
deleted file mode 100644
index 4199109ce3..0000000000
--- a/examples/network/bearermonitor/sessionwidget.ui
+++ /dev/null
@@ -1,307 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>SessionWidget</class>
- <widget class="QWidget" name="SessionWidget">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>340</width>
- <height>276</height>
- </rect>
- </property>
- <property name="windowTitle">
- <string>Session Details</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_2">
- <item>
- <layout class="QVBoxLayout" name="verticalLayout">
- <item>
- <layout class="QHBoxLayout" name="sessionIdLayout">
- <item>
- <widget class="QLabel" name="sessionIdLabel">
- <property name="text">
- <string>Session ID:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="sessionId">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="sessionStateLayout">
- <item>
- <widget class="QLabel" name="sessionStateLabel">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Session State:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="sessionState">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Invalid</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="configurationLayout">
- <item>
- <widget class="QLabel" name="configurationLabel">
- <property name="text">
- <string>Configuration:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="configuration">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="bearerLayout">
- <item>
- <widget class="QLabel" name="bearerLabel">
- <property name="text">
- <string>Bearer:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="bearer">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="interfaceNameLayout">
- <item>
- <widget class="QLabel" name="interfaceNameLabel">
- <property name="text">
- <string>Interface Name:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="interfaceName">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="interfaceGuidLayout">
- <item>
- <widget class="QLabel" name="interfaceGuidLabel">
- <property name="text">
- <string>Interface GUID:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="interfaceGuid">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="lastErrorLayout">
- <item>
- <widget class="QLabel" name="lastErrorLabel">
- <property name="text">
- <string>Last Error:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="lastError">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="errorStringLayout">
- <item>
- <widget class="QLabel" name="errorStringLabel">
- <property name="text">
- <string>Error String:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="errorString">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_3">
- <item>
- <widget class="QLabel" name="rxData">
- <property name="text">
- <string>0</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignCenter</set>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="txData">
- <property name="text">
- <string>0</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignCenter</set>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_4">
- <item>
- <widget class="QLabel" name="label_3">
- <property name="text">
- <string>Active Time:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="activeTime">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>0 seconds</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout">
- <item>
- <widget class="QPushButton" name="openSessionButton">
- <property name="text">
- <string>Open</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="openSyncSessionButton">
- <property name="text">
- <string>Blocking Open</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_2">
- <item>
- <widget class="QPushButton" name="closeSessionButton">
- <property name="text">
- <string>Close</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="stopSessionButton">
- <property name="text">
- <string>Stop</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- <resources/>
- <connections/>
-</ui>
diff --git a/examples/network/fortuneclient/client.cpp b/examples/network/fortuneclient/client.cpp
index 4d3a318a7b..0ccbf51df8 100644
--- a/examples/network/fortuneclient/client.cpp
+++ b/examples/network/fortuneclient/client.cpp
@@ -150,29 +150,6 @@ Client::Client(QWidget *parent)
setWindowTitle(QGuiApplication::applicationDisplayName());
portLineEdit->setFocus();
-
- QNetworkConfigurationManager manager;
- if (manager.capabilities() & QNetworkConfigurationManager::NetworkSessionRequired) {
- // Get saved network configuration
- QSettings settings(QSettings::UserScope, QLatin1String("QtProject"));
- settings.beginGroup(QLatin1String("QtNetwork"));
- const QString id = settings.value(QLatin1String("DefaultNetworkConfiguration")).toString();
- settings.endGroup();
-
- // If the saved network configuration is not currently discovered use the system default
- QNetworkConfiguration config = manager.configurationFromIdentifier(id);
- if ((config.state() & QNetworkConfiguration::Discovered) !=
- QNetworkConfiguration::Discovered) {
- config = manager.defaultConfiguration();
- }
-
- networkSession = new QNetworkSession(config, this);
- connect(networkSession, &QNetworkSession::opened, this, &Client::sessionOpened);
-
- getFortuneButton->setEnabled(false);
- statusLabel->setText(tr("Opening network session."));
- networkSession->open();
- }
//! [5]
}
//! [5]
@@ -241,30 +218,7 @@ void Client::displayError(QAbstractSocket::SocketError socketError)
void Client::enableGetFortuneButton()
{
- getFortuneButton->setEnabled((!networkSession || networkSession->isOpen()) &&
- !hostCombo->currentText().isEmpty() &&
+ getFortuneButton->setEnabled(!hostCombo->currentText().isEmpty() &&
!portLineEdit->text().isEmpty());
}
-
-void Client::sessionOpened()
-{
- // Save the used configuration
- QNetworkConfiguration config = networkSession->configuration();
- QString id;
- if (config.type() == QNetworkConfiguration::UserChoice)
- id = networkSession->sessionProperty(QLatin1String("UserChoiceConfiguration")).toString();
- else
- id = config.identifier();
-
- QSettings settings(QSettings::UserScope, QLatin1String("QtProject"));
- settings.beginGroup(QLatin1String("QtNetwork"));
- settings.setValue(QLatin1String("DefaultNetworkConfiguration"), id);
- settings.endGroup();
-
- statusLabel->setText(tr("This examples requires that you run the "
- "Fortune Server example as well."));
-
- enableGetFortuneButton();
-}
-
diff --git a/examples/network/fortuneclient/client.h b/examples/network/fortuneclient/client.h
index ac335acb83..80177bacbf 100644
--- a/examples/network/fortuneclient/client.h
+++ b/examples/network/fortuneclient/client.h
@@ -61,7 +61,6 @@ class QLabel;
class QLineEdit;
class QPushButton;
class QTcpSocket;
-class QNetworkSession;
QT_END_NAMESPACE
//! [0]
@@ -77,7 +76,6 @@ private slots:
void readFortune();
void displayError(QAbstractSocket::SocketError socketError);
void enableGetFortuneButton();
- void sessionOpened();
private:
QComboBox *hostCombo = nullptr;
@@ -88,8 +86,6 @@ private:
QTcpSocket *tcpSocket = nullptr;
QDataStream in;
QString currentFortune;
-
- QNetworkSession *networkSession = nullptr;
};
//! [0]
diff --git a/examples/network/fortuneserver/server.cpp b/examples/network/fortuneserver/server.cpp
index 7db81fe07a..c91b6a5c0c 100644
--- a/examples/network/fortuneserver/server.cpp
+++ b/examples/network/fortuneserver/server.cpp
@@ -61,29 +61,7 @@ Server::Server(QWidget *parent)
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
statusLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
- QNetworkConfigurationManager manager;
- if (manager.capabilities() & QNetworkConfigurationManager::NetworkSessionRequired) {
- // Get saved network configuration
- QSettings settings(QSettings::UserScope, QLatin1String("QtProject"));
- settings.beginGroup(QLatin1String("QtNetwork"));
- const QString id = settings.value(QLatin1String("DefaultNetworkConfiguration")).toString();
- settings.endGroup();
-
- // If the saved network configuration is not currently discovered use the system default
- QNetworkConfiguration config = manager.configurationFromIdentifier(id);
- if ((config.state() & QNetworkConfiguration::Discovered) !=
- QNetworkConfiguration::Discovered) {
- config = manager.defaultConfiguration();
- }
-
- networkSession = new QNetworkSession(config, this);
- connect(networkSession, &QNetworkSession::opened, this, &Server::sessionOpened);
-
- statusLabel->setText(tr("Opening network session."));
- networkSession->open();
- } else {
- sessionOpened();
- }
+ initServer();
//! [2]
fortunes << tr("You've been leading a dog's life. Stay off the furniture.")
@@ -128,23 +106,8 @@ Server::Server(QWidget *parent)
setWindowTitle(QGuiApplication::applicationDisplayName());
}
-void Server::sessionOpened()
+void Server::initServer()
{
- // Save the used configuration
- if (networkSession) {
- QNetworkConfiguration config = networkSession->configuration();
- QString id;
- if (config.type() == QNetworkConfiguration::UserChoice)
- id = networkSession->sessionProperty(QLatin1String("UserChoiceConfiguration")).toString();
- else
- id = config.identifier();
-
- QSettings settings(QSettings::UserScope, QLatin1String("QtProject"));
- settings.beginGroup(QLatin1String("QtNetwork"));
- settings.setValue(QLatin1String("DefaultNetworkConfiguration"), id);
- settings.endGroup();
- }
-
//! [0] //! [1]
tcpServer = new QTcpServer(this);
if (!tcpServer->listen()) {
diff --git a/examples/network/fortuneserver/server.h b/examples/network/fortuneserver/server.h
index c5bfa7d928..96d7145148 100644
--- a/examples/network/fortuneserver/server.h
+++ b/examples/network/fortuneserver/server.h
@@ -58,7 +58,6 @@
QT_BEGIN_NAMESPACE
class QLabel;
class QTcpServer;
-class QNetworkSession;
QT_END_NAMESPACE
//! [0]
@@ -70,14 +69,14 @@ public:
explicit Server(QWidget *parent = nullptr);
private slots:
- void sessionOpened();
void sendFortune();
private:
+ void initServer();
+
QLabel *statusLabel = nullptr;
QTcpServer *tcpServer = nullptr;
QVector<QString> fortunes;
- QNetworkSession *networkSession = nullptr;
};
//! [0]
diff --git a/examples/network/network-chat/main.cpp b/examples/network/network-chat/main.cpp
index f88e29977b..029c18f0ff 100644
--- a/examples/network/network-chat/main.cpp
+++ b/examples/network/network-chat/main.cpp
@@ -53,50 +53,11 @@
#include "chatdialog.h"
#include <QtCore/QSettings>
-#include <QtNetwork/QNetworkConfigurationManager>
-#include <QtNetwork/QNetworkSession>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
- QNetworkConfigurationManager manager;
- if (manager.capabilities() & QNetworkConfigurationManager::NetworkSessionRequired) {
- // Get saved network configuration
- QSettings settings(QSettings::UserScope, QLatin1String("QtProject"));
- settings.beginGroup(QLatin1String("QtNetwork"));
- const QString id = settings.value(QLatin1String("DefaultNetworkConfiguration")).toString();
- settings.endGroup();
-
- // If the saved network configuration is not currently discovered use the system default
- QNetworkConfiguration config = manager.configurationFromIdentifier(id);
- if ((config.state() & QNetworkConfiguration::Discovered) !=
- QNetworkConfiguration::Discovered) {
- config = manager.defaultConfiguration();
- }
-
- QNetworkSession *networkSession = new QNetworkSession(config, &app);
- networkSession->open();
- networkSession->waitForOpened();
-
- if (networkSession->isOpen()) {
- // Save the used configuration
- QNetworkConfiguration config = networkSession->configuration();
- QString id;
- if (config.type() == QNetworkConfiguration::UserChoice) {
- id = networkSession->sessionProperty(
- QLatin1String("UserChoiceConfiguration")).toString();
- } else {
- id = config.identifier();
- }
-
- QSettings settings(QSettings::UserScope, QLatin1String("QtProject"));
- settings.beginGroup(QLatin1String("QtNetwork"));
- settings.setValue(QLatin1String("DefaultNetworkConfiguration"), id);
- settings.endGroup();
- }
- }
-
ChatDialog dialog;
dialog.show();
return app.exec();
diff --git a/examples/network/network.pro b/examples/network/network.pro
index af3c0df43e..3f851d7c71 100644
--- a/examples/network/network.pro
+++ b/examples/network/network.pro
@@ -19,15 +19,11 @@ qtHaveModule(widgets) {
multicastreceiver \
multicastsender
- qtConfig(bearermanagement) {
- qtConfig(processenvironment): SUBDIRS += network-chat
+ qtConfig(processenvironment): SUBDIRS += network-chat
- SUBDIRS += \
- bearermonitor \
- fortuneclient \
- fortuneserver
-
- }
+ SUBDIRS += \
+ fortuneclient \
+ fortuneserver
qtConfig(ssl): SUBDIRS += securesocketclient
qtConfig(dtls): SUBDIRS += secureudpserver secureudpclient
diff --git a/examples/widgets/doc/src/syntaxhighlighter.qdoc b/examples/widgets/doc/src/syntaxhighlighter.qdoc
index 8583d86114..618b387ed5 100644
--- a/examples/widgets/doc/src/syntaxhighlighter.qdoc
+++ b/examples/widgets/doc/src/syntaxhighlighter.qdoc
@@ -246,11 +246,7 @@
\section1 Other Code Editor Features
- It is possible to implement parenthesis matching with
- QSyntaxHighlighter. The "Matching Parentheses with
- QSyntaxHighlighter" article in Qt Quarterly 31
- (\l{http://doc.qt.io/archives/qq/}) implements this. We also have
- the \l{Code Editor Example}, which shows how to implement line
+ The \l{Code Editor Example} shows how to implement line
numbers and how to highlight the current line.
*/
diff --git a/examples/widgets/widgets/tablet/tabletcanvas.cpp b/examples/widgets/widgets/tablet/tabletcanvas.cpp
index 59ca608cef..90a5017500 100644
--- a/examples/widgets/widgets/tablet/tabletcanvas.cpp
+++ b/examples/widgets/widgets/tablet/tabletcanvas.cpp
@@ -106,7 +106,7 @@ void TabletCanvas::tabletEvent(QTabletEvent *event)
break;
case QEvent::TabletMove:
#ifndef Q_OS_IOS
- if (event->device() == QTabletEvent::RotationStylus)
+ if (event->deviceType() == QTabletEvent::RotationStylus)
updateCursor(event);
#endif
if (m_deviceDown) {
@@ -161,7 +161,7 @@ void TabletCanvas::paintPixmap(QPainter &painter, QTabletEvent *event)
static qreal maxPenRadius = pressureToWidth(1.0);
painter.setRenderHint(QPainter::Antialiasing);
- switch (event->device()) {
+ switch (event->deviceType()) {
//! [6]
case QTabletEvent::Airbrush:
{
@@ -251,7 +251,7 @@ void TabletCanvas::updateBrush(const QTabletEvent *event)
m_color.setAlphaF(event->pressure());
break;
case TangentialPressureValuator:
- if (event->device() == QTabletEvent::Airbrush)
+ if (event->deviceType() == QTabletEvent::Airbrush)
m_color.setAlphaF(qMax(0.01, (event->tangentialPressure() + 1.0) / 2.0));
else
m_color.setAlpha(255);
@@ -312,7 +312,7 @@ void TabletCanvas::updateCursor(const QTabletEvent *event)
if (event->pointerType() == QTabletEvent::Eraser) {
cursor = QCursor(QPixmap(":/images/cursor-eraser.png"), 3, 28);
} else {
- switch (event->device()) {
+ switch (event->deviceType()) {
case QTabletEvent::Stylus:
cursor = QCursor(QPixmap(":/images/cursor-pencil.png"), 0, 0);
break;
diff --git a/mkspecs/features/lrelease.prf b/mkspecs/features/lrelease.prf
index 1e828b64df..f611c74184 100644
--- a/mkspecs/features/lrelease.prf
+++ b/mkspecs/features/lrelease.prf
@@ -35,6 +35,7 @@ embed_translations {
!isEmpty(QM_FILES_INSTALL_PATH) {
qm_files.files = $$QM_FILES
qm_files.path = $$QM_FILES_INSTALL_PATH
+ qm_files.CONFIG = no_check_exist
INSTALLS += qm_files
}
lrelease.CONFIG += target_predeps no_clean
diff --git a/mkspecs/features/wasm/default_pre.prf b/mkspecs/features/wasm/default_pre.prf
index 2760889929..d092149b32 100644
--- a/mkspecs/features/wasm/default_pre.prf
+++ b/mkspecs/features/wasm/default_pre.prf
@@ -1,2 +1,2 @@
-load(default_pre)
load(emcc_ver)
+load(default_pre)
diff --git a/mkspecs/features/wasm/emcc_ver.prf b/mkspecs/features/wasm/emcc_ver.prf
index 505a321d64..411f53e95d 100644
--- a/mkspecs/features/wasm/emcc_ver.prf
+++ b/mkspecs/features/wasm/emcc_ver.prf
@@ -3,7 +3,9 @@ defineReplace(qtEmccRecommendedVersion) {
}
defineReplace(qtSystemEmccVersion) {
- E_VERSION = $$system("emcc -v 2>&1 | perl -alne $$shell_quote($_ = $F[9]; s/://; print;) ")
+ EMCC = $$system("emcc -v 2>&1", lines)
+ EMCC_LINE = $$find(EMCC, "^.*\b(emcc)\b.*$")
+ E_VERSION = $$section(EMCC_LINE, " ", 9,9)
return ($${E_VERSION})
}
diff --git a/qmake/doc/src/qmake-manual.qdoc b/qmake/doc/src/qmake-manual.qdoc
index 4c71ceb929..1e1e23495c 100644
--- a/qmake/doc/src/qmake-manual.qdoc
+++ b/qmake/doc/src/qmake-manual.qdoc
@@ -960,6 +960,10 @@
default is used.
\row \li thread \li Thread support is enabled. This is enabled when CONFIG
includes \c qt, which is the default.
+ \row \li utf8_source \li Specifies that the project's source files use the
+ UTF-8 encoding. By default, the compiler default is used.
+ \row \li hide_symbols \li Set the default visibility of symbols in the binary
+ to hidden. By default, the compiler default is used.
\row \li c99 \li C99 support is enabled. This option has no effect if
the compiler does not support C99, or can't select the C standard.
By default, the compiler default is used.
diff --git a/qmake/generators/unix/unixmake2.cpp b/qmake/generators/unix/unixmake2.cpp
index 4a6a42c7d2..9789c9c8e5 100644
--- a/qmake/generators/unix/unixmake2.cpp
+++ b/qmake/generators/unix/unixmake2.cpp
@@ -558,6 +558,8 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
t << destdir_d << depVar("TARGET") << ": " << depVar("PRE_TARGETDEPS") << ' '
<< incr_deps << " $(SUBLIBS) " << target_deps << ' ' << depVar("POST_TARGETDEPS");
} else {
+ ProStringList &cmd = project->values("QMAKE_LINK_SHLIB_CMD");
+ cmd[0] = cmd.at(0).toQString().replace(QLatin1String("$(OBJECTS)"), objectParts.second);
t << destdir_d << depVar("TARGET") << ": " << depVar("PRE_TARGETDEPS")
<< " $(OBJECTS) $(SUBLIBS) $(OBJCOMP) " << target_deps
<< ' ' << depVar("POST_TARGETDEPS");
diff --git a/qmake/generators/win32/winmakefile.cpp b/qmake/generators/win32/winmakefile.cpp
index 86d10c213c..3ec2704625 100644
--- a/qmake/generators/win32/winmakefile.cpp
+++ b/qmake/generators/win32/winmakefile.cpp
@@ -736,6 +736,18 @@ QString Win32MakefileGenerator::defaultInstall(const QString &t)
if(targetdir.right(1) != Option::dir_sep)
targetdir += Option::dir_sep;
+ const ProStringList &targets = project->values(ProKey(t + ".targets"));
+ for (int i = 0; i < targets.size(); ++i) {
+ QString src = targets.at(i).toQString(),
+ dst = escapeFilePath(filePrefixRoot(root, targetdir + src.section('/', -1)));
+ if (!ret.isEmpty())
+ ret += "\n\t";
+ ret += "$(QINSTALL) " + escapeFilePath(Option::fixPathToTargetOS(src, false)) + ' ' + dst;
+ if (!uninst.isEmpty())
+ uninst.append("\n\t");
+ uninst.append("-$(DEL_FILE) " + dst);
+ }
+
if(t == "target" && project->first("TEMPLATE") == "lib") {
if(project->isActiveConfig("create_prl") && !project->isActiveConfig("no_install_prl") &&
!project->isEmpty("QMAKE_INTERNAL_PRL_FILE")) {
@@ -744,6 +756,8 @@ QString Win32MakefileGenerator::defaultInstall(const QString &t)
if(slsh != -1)
dst_prl = dst_prl.right(dst_prl.length() - slsh - 1);
dst_prl = filePrefixRoot(root, targetdir + dst_prl);
+ if (!ret.isEmpty())
+ ret += "\n\t";
ret += installMetaFile(ProKey("QMAKE_PRL_INSTALL_REPLACE"), project->first("QMAKE_INTERNAL_PRL_FILE").toQString(), dst_prl);
if(!uninst.isEmpty())
uninst.append("\n\t");
diff --git a/src/3rdparty/md4c/md4c.c b/src/3rdparty/md4c/md4c.c
index 3745cf3e46..b0ef739b3c 100644
--- a/src/3rdparty/md4c/md4c.c
+++ b/src/3rdparty/md4c/md4c.c
@@ -2,7 +2,7 @@
* MD4C: Markdown parser for C
* (http://github.com/mity/md4c)
*
- * Copyright (c) 2016-2019 Martin Mitas
+ * Copyright (c) 2016-2020 Martin Mitas
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -35,14 +35,23 @@
*** Miscellaneous Stuff ***
*****************************/
-#ifdef _MSC_VER
- /* MSVC does not understand "inline" when building as pure C (not C++).
- * However it understands "__inline" */
- #ifndef __cplusplus
+#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199409L
+ /* C89/90 or old compilers in general may not understand "inline". */
+ #if defined __GNUC__
+ #define inline __inline__
+ #elif defined _MSC_VER
#define inline __inline
+ #else
+ #define inline
#endif
#endif
+/* Make the UTF-8 support the default. */
+#if !defined MD4C_USE_ASCII && !defined MD4C_USE_UTF8 && !defined MD4C_USE_UTF16
+ #define MD4C_USE_UTF8
+#endif
+
+/* Magic for making wide literals with MD4C_USE_UTF16. */
#ifdef _T
#undef _T
#endif
@@ -127,7 +136,7 @@ struct MD_CTX_tag {
#endif
/* For resolving of inline spans. */
- MD_MARKCHAIN mark_chains[12];
+ MD_MARKCHAIN mark_chains[13];
#define PTR_CHAIN ctx->mark_chains[0]
#define TABLECELLBOUNDARIES ctx->mark_chains[1]
#define ASTERISK_OPENERS_extraword_mod3_0 ctx->mark_chains[2]
@@ -137,11 +146,12 @@ struct MD_CTX_tag {
#define ASTERISK_OPENERS_intraword_mod3_1 ctx->mark_chains[6]
#define ASTERISK_OPENERS_intraword_mod3_2 ctx->mark_chains[7]
#define UNDERSCORE_OPENERS ctx->mark_chains[8]
-#define TILDE_OPENERS ctx->mark_chains[9]
-#define BRACKET_OPENERS ctx->mark_chains[10]
-#define DOLLAR_OPENERS ctx->mark_chains[11]
+#define TILDE_OPENERS_1 ctx->mark_chains[9]
+#define TILDE_OPENERS_2 ctx->mark_chains[10]
+#define BRACKET_OPENERS ctx->mark_chains[11]
+#define DOLLAR_OPENERS ctx->mark_chains[12]
#define OPENERS_CHAIN_FIRST 2
-#define OPENERS_CHAIN_LAST 11
+#define OPENERS_CHAIN_LAST 12
int n_table_cell_boundaries;
@@ -263,6 +273,9 @@ struct MD_VERBATIMLINE_tag {
#define CH(off) (ctx->text[(off)])
#define STR(off) (ctx->text + (off))
+/* Check whether the pointer points into ctx->text. */
+#define IS_INPUT_STR(ptr) (ctx->text <= (ptr) && (ptr) < (ctx->text + ctx->size))
+
/* Character classification.
* Note we assume ASCII compatibility of code points < 128 here. */
#define ISIN_(ch, ch_min, ch_max) ((ch_min) <= (unsigned)(ch) && (unsigned)(ch) <= (ch_max))
@@ -297,16 +310,14 @@ struct MD_VERBATIMLINE_tag {
#define ISDIGIT(off) ISDIGIT_(CH(off))
#define ISXDIGIT(off) ISXDIGIT_(CH(off))
#define ISALNUM(off) ISALNUM_(CH(off))
-static inline const CHAR*
-md_strchr(const CHAR* str, CHAR ch)
-{
- OFF i;
- for(i = 0; str[i] != _T('\0'); i++) {
- if(ch == str[i])
- return (str + i);
- }
- return NULL;
-}
+
+
+#if defined MD4C_USE_UTF16
+ #define md_strchr wcschr
+#else
+ #define md_strchr strchr
+#endif
+
/* Case insensitive check of string equality. */
static inline int
@@ -364,89 +375,89 @@ md_text_with_null_replacement(MD_CTX* ctx, MD_TEXTTYPE type, const CHAR* str, SZ
}
-#define MD_CHECK(func) \
- do { \
- ret = (func); \
- if(ret < 0) \
- goto abort; \
+#define MD_CHECK(func) \
+ do { \
+ ret = (func); \
+ if(ret < 0) \
+ goto abort; \
} while(0)
-#define MD_TEMP_BUFFER(sz) \
- do { \
- if(sz > ctx->alloc_buffer) { \
- CHAR* new_buffer; \
- SZ new_size = ((sz) + (sz) / 2 + 128) & ~127; \
- \
- new_buffer = realloc(ctx->buffer, new_size); \
- if(new_buffer == NULL) { \
- MD_LOG("realloc() failed."); \
- ret = -1; \
- goto abort; \
- } \
- \
- ctx->buffer = new_buffer; \
- ctx->alloc_buffer = new_size; \
- } \
+#define MD_TEMP_BUFFER(sz) \
+ do { \
+ if(sz > ctx->alloc_buffer) { \
+ CHAR* new_buffer; \
+ SZ new_size = ((sz) + (sz) / 2 + 128) & ~127; \
+ \
+ new_buffer = realloc(ctx->buffer, new_size); \
+ if(new_buffer == NULL) { \
+ MD_LOG("realloc() failed."); \
+ ret = -1; \
+ goto abort; \
+ } \
+ \
+ ctx->buffer = new_buffer; \
+ ctx->alloc_buffer = new_size; \
+ } \
} while(0)
-#define MD_ENTER_BLOCK(type, arg) \
- do { \
- ret = ctx->parser.enter_block((type), (arg), ctx->userdata); \
- if(ret != 0) { \
- MD_LOG("Aborted from enter_block() callback."); \
- goto abort; \
- } \
+#define MD_ENTER_BLOCK(type, arg) \
+ do { \
+ ret = ctx->parser.enter_block((type), (arg), ctx->userdata); \
+ if(ret != 0) { \
+ MD_LOG("Aborted from enter_block() callback."); \
+ goto abort; \
+ } \
} while(0)
-#define MD_LEAVE_BLOCK(type, arg) \
- do { \
- ret = ctx->parser.leave_block((type), (arg), ctx->userdata); \
- if(ret != 0) { \
- MD_LOG("Aborted from leave_block() callback."); \
- goto abort; \
- } \
+#define MD_LEAVE_BLOCK(type, arg) \
+ do { \
+ ret = ctx->parser.leave_block((type), (arg), ctx->userdata); \
+ if(ret != 0) { \
+ MD_LOG("Aborted from leave_block() callback."); \
+ goto abort; \
+ } \
} while(0)
-#define MD_ENTER_SPAN(type, arg) \
- do { \
- ret = ctx->parser.enter_span((type), (arg), ctx->userdata); \
- if(ret != 0) { \
- MD_LOG("Aborted from enter_span() callback."); \
- goto abort; \
- } \
+#define MD_ENTER_SPAN(type, arg) \
+ do { \
+ ret = ctx->parser.enter_span((type), (arg), ctx->userdata); \
+ if(ret != 0) { \
+ MD_LOG("Aborted from enter_span() callback."); \
+ goto abort; \
+ } \
} while(0)
-#define MD_LEAVE_SPAN(type, arg) \
- do { \
- ret = ctx->parser.leave_span((type), (arg), ctx->userdata); \
- if(ret != 0) { \
- MD_LOG("Aborted from leave_span() callback."); \
- goto abort; \
- } \
+#define MD_LEAVE_SPAN(type, arg) \
+ do { \
+ ret = ctx->parser.leave_span((type), (arg), ctx->userdata); \
+ if(ret != 0) { \
+ MD_LOG("Aborted from leave_span() callback."); \
+ goto abort; \
+ } \
} while(0)
-#define MD_TEXT(type, str, size) \
- do { \
- if(size > 0) { \
- ret = ctx->parser.text((type), (str), (size), ctx->userdata); \
- if(ret != 0) { \
- MD_LOG("Aborted from text() callback."); \
- goto abort; \
- } \
- } \
+#define MD_TEXT(type, str, size) \
+ do { \
+ if(size > 0) { \
+ ret = ctx->parser.text((type), (str), (size), ctx->userdata); \
+ if(ret != 0) { \
+ MD_LOG("Aborted from text() callback."); \
+ goto abort; \
+ } \
+ } \
} while(0)
-#define MD_TEXT_INSECURE(type, str, size) \
- do { \
- if(size > 0) { \
- ret = md_text_with_null_replacement(ctx, type, str, size); \
- if(ret != 0) { \
- MD_LOG("Aborted from text() callback."); \
- goto abort; \
- } \
- } \
+#define MD_TEXT_INSECURE(type, str, size) \
+ do { \
+ if(size > 0) { \
+ ret = md_text_with_null_replacement(ctx, type, str, size); \
+ if(ret != 0) { \
+ MD_LOG("Aborted from text() callback."); \
+ goto abort; \
+ } \
+ } \
} while(0)
@@ -1329,8 +1340,9 @@ md_build_attr_append_substr(MD_CTX* ctx, MD_ATTRIBUTE_BUILD* build,
MD_TEXTTYPE* new_substr_types;
OFF* new_substr_offsets;
- build->substr_alloc = (build->substr_alloc == 0 ? 8 : build->substr_alloc * 2);
-
+ build->substr_alloc = (build->substr_alloc > 0
+ ? build->substr_alloc + build->substr_alloc / 2
+ : 8);
new_substr_types = (MD_TEXTTYPE*) realloc(build->substr_types,
build->substr_alloc * sizeof(MD_TEXTTYPE));
if(new_substr_types == NULL) {
@@ -1456,8 +1468,8 @@ abort:
*** Dictionary of Reference Definitions ***
*********************************************/
-#define MD_FNV1A_BASE 2166136261
-#define MD_FNV1A_PRIME 16777619
+#define MD_FNV1A_BASE 2166136261U
+#define MD_FNV1A_PRIME 16777619U
static inline unsigned
md_fnv1a(unsigned base, const void* data, size_t n)
@@ -1479,9 +1491,7 @@ struct MD_REF_DEF_tag {
CHAR* label;
CHAR* title;
unsigned hash;
- SZ label_size : 24;
- unsigned label_needs_free : 1;
- unsigned title_needs_free : 1;
+ SZ label_size;
SZ title_size;
OFF dest_beg;
OFF dest_end;
@@ -1530,7 +1540,7 @@ md_link_label_cmp_load_fold_info(const CHAR* label, OFF off, SZ size,
SZ char_size;
if(off >= size) {
- /* Treat end of link label as a whitespace. */
+ /* Treat end of a link label as a whitespace. */
goto whitespace;
}
@@ -1554,7 +1564,7 @@ md_link_label_cmp_load_fold_info(const CHAR* label, OFF off, SZ size,
whitespace:
fold_info->codepoints[0] = _T(' ');
fold_info->n_codepoints = 1;
- return off;
+ return md_skip_unicode_whitespace(label, off, size);
}
static int
@@ -1572,7 +1582,7 @@ md_link_label_cmp(const CHAR* a_label, SZ a_size, const CHAR* b_label, SZ b_size
a_off = md_skip_unicode_whitespace(a_label, 0, a_size);
b_off = md_skip_unicode_whitespace(b_label, 0, b_size);
- while(!a_reached_end && !b_reached_end) {
+ while(!a_reached_end || !b_reached_end) {
/* If needed, load fold info for next char. */
if(a_fi_off >= a_fi.n_codepoints) {
a_fi_off = 0;
@@ -1618,7 +1628,7 @@ md_ref_def_cmp(const void* a, const void* b)
}
static int
-md_ref_def_cmp_stable(const void* a, const void* b)
+md_ref_def_cmp_for_sort(const void* a, const void* b)
{
int cmp;
@@ -1671,6 +1681,7 @@ md_build_ref_def_hashtable(MD_CTX* ctx)
bucket = ctx->ref_def_hashtable[def->hash % ctx->ref_def_hashtable_size];
if(bucket == NULL) {
+ /* The bucket is empty. Make it just point to the def. */
ctx->ref_def_hashtable[def->hash % ctx->ref_def_hashtable_size] = def;
continue;
}
@@ -1682,12 +1693,12 @@ md_build_ref_def_hashtable(MD_CTX* ctx)
MD_REF_DEF* old_def = (MD_REF_DEF*) bucket;
if(md_link_label_cmp(def->label, def->label_size, old_def->label, old_def->label_size) == 0) {
- /* Ignore this ref. def. */
+ /* Duplicate label: Ignore this ref. def. */
continue;
}
- /* Make the bucket capable of holding more ref. defs. */
- list = (MD_REF_DEF_LIST*) malloc(sizeof(MD_REF_DEF_LIST) + 4 * sizeof(MD_REF_DEF*));
+ /* Make the bucket complex, i.e. able to hold more ref. defs. */
+ list = (MD_REF_DEF_LIST*) malloc(sizeof(MD_REF_DEF_LIST) + 2 * sizeof(MD_REF_DEF*));
if(list == NULL) {
MD_LOG("malloc() failed.");
goto abort;
@@ -1695,22 +1706,28 @@ md_build_ref_def_hashtable(MD_CTX* ctx)
list->ref_defs[0] = old_def;
list->ref_defs[1] = def;
list->n_ref_defs = 2;
- list->alloc_ref_defs = 4;
+ list->alloc_ref_defs = 2;
ctx->ref_def_hashtable[def->hash % ctx->ref_def_hashtable_size] = list;
continue;
}
- /* Append the def to the bucket list. */
+ /* Append the def to the complex bucket list.
+ *
+ * Note in this case we ignore potential duplicates to avoid expensive
+ * iterating over the complex bucket. Below, we revisit all the complex
+ * buckets and handle it more cheaply after the complex bucket contents
+ * is sorted. */
list = (MD_REF_DEF_LIST*) bucket;
if(list->n_ref_defs >= list->alloc_ref_defs) {
+ int alloc_ref_defs = list->alloc_ref_defs + list->alloc_ref_defs / 2;
MD_REF_DEF_LIST* list_tmp = (MD_REF_DEF_LIST*) realloc(list,
- sizeof(MD_REF_DEF_LIST) + 2 * list->alloc_ref_defs * sizeof(MD_REF_DEF*));
+ sizeof(MD_REF_DEF_LIST) + alloc_ref_defs * sizeof(MD_REF_DEF*));
if(list_tmp == NULL) {
MD_LOG("realloc() failed.");
goto abort;
}
list = list_tmp;
- list->alloc_ref_defs *= 2;
+ list->alloc_ref_defs = alloc_ref_defs;
ctx->ref_def_hashtable[def->hash % ctx->ref_def_hashtable_size] = list;
}
@@ -1729,9 +1746,12 @@ md_build_ref_def_hashtable(MD_CTX* ctx)
continue;
list = (MD_REF_DEF_LIST*) bucket;
- qsort(list->ref_defs, list->n_ref_defs, sizeof(MD_REF_DEF*), md_ref_def_cmp_stable);
+ qsort(list->ref_defs, list->n_ref_defs, sizeof(MD_REF_DEF*), md_ref_def_cmp_for_sort);
- /* Disable duplicates. */
+ /* Disable all duplicates in the complex bucket by forcing all such
+ * records to point to the 1st such ref. def. I.e. no matter which
+ * record is found during the lookup, it will always point to the right
+ * ref. def. in ctx->ref_defs[]. */
for(j = 1; j < list->n_ref_defs; j++) {
if(md_ref_def_cmp(&list->ref_defs[j-1], &list->ref_defs[j]) == 0)
list->ref_defs[j] = list->ref_defs[j-1];
@@ -2055,9 +2075,8 @@ md_is_link_reference_definition(MD_CTX* ctx, const MD_LINE* lines, int n_lines)
OFF label_contents_end;
int label_contents_line_index = -1;
int label_is_multiline;
- CHAR* label;
+ CHAR* label = NULL;
SZ label_size;
- int label_needs_free = FALSE;
OFF dest_contents_beg;
OFF dest_contents_end;
OFF title_contents_beg;
@@ -2123,23 +2142,22 @@ md_is_link_reference_definition(MD_CTX* ctx, const MD_LINE* lines, int n_lines)
if(!label_is_multiline) {
label = (CHAR*) STR(label_contents_beg);
label_size = label_contents_end - label_contents_beg;
- label_needs_free = FALSE;
} else {
MD_CHECK(md_merge_lines_alloc(ctx, label_contents_beg, label_contents_end,
lines + label_contents_line_index, n_lines - label_contents_line_index,
_T(' '), &label, &label_size));
- label_needs_free = TRUE;
}
/* Store the reference definition. */
if(ctx->n_ref_defs >= ctx->alloc_ref_defs) {
MD_REF_DEF* new_defs;
- ctx->alloc_ref_defs = (ctx->alloc_ref_defs > 0 ? ctx->alloc_ref_defs * 2 : 16);
+ ctx->alloc_ref_defs = (ctx->alloc_ref_defs > 0
+ ? ctx->alloc_ref_defs + ctx->alloc_ref_defs / 2
+ : 16);
new_defs = (MD_REF_DEF*) realloc(ctx->ref_defs, ctx->alloc_ref_defs * sizeof(MD_REF_DEF));
if(new_defs == NULL) {
MD_LOG("realloc() failed.");
- ret = -1;
goto abort;
}
@@ -2151,7 +2169,6 @@ md_is_link_reference_definition(MD_CTX* ctx, const MD_LINE* lines, int n_lines)
def->label = label;
def->label_size = label_size;
- def->label_needs_free = label_needs_free;
def->dest_beg = dest_contents_beg;
def->dest_end = dest_contents_end;
@@ -2166,7 +2183,6 @@ md_is_link_reference_definition(MD_CTX* ctx, const MD_LINE* lines, int n_lines)
MD_CHECK(md_merge_lines_alloc(ctx, title_contents_beg, title_contents_end,
lines + title_contents_line_index, n_lines - title_contents_line_index,
_T('\n'), &def->title, &def->title_size));
- def->title_needs_free = TRUE;
}
/* Success. */
@@ -2175,9 +2191,9 @@ md_is_link_reference_definition(MD_CTX* ctx, const MD_LINE* lines, int n_lines)
abort:
/* Failure. */
- if(label_needs_free)
+ if(!IS_INPUT_STR(label))
free(label);
- return -1;
+ return ret;
}
static int
@@ -2225,7 +2241,7 @@ md_is_link_reference(MD_CTX* ctx, const MD_LINE* lines, int n_lines,
attr->title_needs_free = FALSE;
}
- if(beg_line != end_line)
+ if(!IS_INPUT_STR(label))
free(label);
ret = (def != NULL);
@@ -2339,9 +2355,9 @@ md_free_ref_defs(MD_CTX* ctx)
for(i = 0; i < ctx->n_ref_defs; i++) {
MD_REF_DEF* def = &ctx->ref_defs[i];
- if(def->label_needs_free)
+ if(!IS_INPUT_STR(def->label))
free(def->label);
- if(def->title_needs_free)
+ if(!IS_INPUT_STR(def->title))
free(def->title);
}
@@ -2470,7 +2486,7 @@ md_mark_chain(MD_CTX* ctx, int mark_index)
switch(mark->ch) {
case _T('*'): return md_asterisk_chain(ctx, mark->flags);
case _T('_'): return &UNDERSCORE_OPENERS;
- case _T('~'): return &TILDE_OPENERS;
+ case _T('~'): return (mark->end - mark->beg == 1) ? &TILDE_OPENERS_1 : &TILDE_OPENERS_2;
case _T('['): return &BRACKET_OPENERS;
case _T('|'): return &TABLECELLBOUNDARIES;
default: return NULL;
@@ -2483,7 +2499,9 @@ md_push_mark(MD_CTX* ctx)
if(ctx->n_marks >= ctx->alloc_marks) {
MD_MARK* new_marks;
- ctx->alloc_marks = (ctx->alloc_marks > 0 ? ctx->alloc_marks * 2 : 64);
+ ctx->alloc_marks = (ctx->alloc_marks > 0
+ ? ctx->alloc_marks + ctx->alloc_marks / 2
+ : 64);
new_marks = realloc(ctx->marks, ctx->alloc_marks * sizeof(MD_MARK));
if(new_marks == NULL) {
MD_LOG("realloc() failed.");
@@ -2526,6 +2544,7 @@ md_mark_chain_append(MD_CTX* ctx, MD_MARKCHAIN* chain, int mark_index)
chain->head = mark_index;
ctx->marks[mark_index].prev = chain->tail;
+ ctx->marks[mark_index].next = -1;
chain->tail = mark_index;
}
@@ -2617,7 +2636,7 @@ md_rollback(MD_CTX* ctx, int opener_index, int closer_index, int how)
chain->head = -1;
}
- /* Go backwards so that un-resolved openers are re-added into their
+ /* Go backwards so that unresolved openers are re-added into their
* respective chains, in the right order. */
mark_index = closer_index - 1;
while(mark_index > opener_index) {
@@ -2696,7 +2715,7 @@ md_build_mark_char_map(MD_CTX* ctx)
if(ctx->parser.flags & MD_FLAG_PERMISSIVEWWWAUTOLINKS)
ctx->mark_char_map['.'] = 1;
- if(ctx->parser.flags & MD_FLAG_TABLES)
+ if((ctx->parser.flags & MD_FLAG_TABLES) || (ctx->parser.flags & MD_FLAG_WIKILINKS))
ctx->mark_char_map['|'] = 1;
if(ctx->parser.flags & MD_FLAG_COLLAPSEWHITESPACE) {
@@ -2896,7 +2915,7 @@ md_is_autolink_email(MD_CTX* ctx, OFF beg, OFF max_end, OFF* p_end)
return FALSE;
off++;
- /* Labels delimited with '.'; each label is sequence of 1 - 62 alnum
+ /* Labels delimited with '.'; each label is sequence of 1 - 63 alnum
* characters or '-', but '-' is not allowed as first or last char. */
label_len = 0;
while(off < max_end) {
@@ -2909,7 +2928,7 @@ md_is_autolink_email(MD_CTX* ctx, OFF beg, OFF max_end, OFF* p_end)
else
break;
- if(label_len > 62)
+ if(label_len > 63)
return FALSE;
off++;
@@ -3236,8 +3255,8 @@ md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode)
continue;
}
- /* A potential table cell boundary. */
- if(table_mode && ch == _T('|')) {
+ /* A potential table cell boundary or wiki link label delimiter. */
+ if((table_mode || ctx->parser.flags & MD_FLAG_WIKILINKS) && ch == _T('|')) {
PUSH_MARK(ch, off, off+1, 0);
off++;
continue;
@@ -3250,7 +3269,17 @@ md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode)
while(tmp < line_end && CH(tmp) == _T('~'))
tmp++;
- PUSH_MARK(ch, off, tmp, MD_MARK_POTENTIAL_OPENER | MD_MARK_POTENTIAL_CLOSER);
+ if(tmp - off < 3) {
+ unsigned flags = 0;
+
+ if(tmp < line_end && !ISUNICODEWHITESPACE(tmp))
+ flags |= MD_MARK_POTENTIAL_OPENER;
+ if(off > line->beg && !ISUNICODEWHITESPACEBEFORE(off))
+ flags |= MD_MARK_POTENTIAL_CLOSER;
+ if(flags != 0)
+ PUSH_MARK(ch, off, tmp, flags);
+ }
+
off = tmp;
continue;
}
@@ -3398,6 +3427,91 @@ md_resolve_links(MD_CTX* ctx, const MD_LINE* lines, int n_lines)
continue;
}
+ /* Recognize and resolve wiki links.
+ * Wiki-links maybe '[[destination]]' or '[[destination|label]]'.
+ */
+ if ((ctx->parser.flags & MD_FLAG_WIKILINKS) &&
+ (opener->end - opener->beg == 1) && /* not image */
+ next_opener != NULL && /* double '[' opener */
+ next_opener->ch == '[' &&
+ (next_opener->beg == opener->beg - 1) &&
+ (next_opener->end - next_opener->beg == 1) &&
+ next_closer != NULL && /* double ']' closer */
+ next_closer->ch == ']' &&
+ (next_closer->beg == closer->beg + 1) &&
+ (next_closer->end - next_closer->beg == 1))
+ {
+ MD_MARK* delim = NULL;
+ int delim_index;
+ OFF dest_beg, dest_end;
+
+ is_link = TRUE;
+
+ /* We don't allow destination to be longer then 100 characters.
+ * Lets scan to see whether there is '|'. (If not then the whole
+ * wiki-link has to be below the 100 characters.) */
+ delim_index = opener_index + 1;
+ while(delim_index < closer_index) {
+ MD_MARK* m = &ctx->marks[delim_index];
+ if(m->ch == '|') {
+ delim = m;
+ break;
+ }
+ if(m->ch != 'D' && m->beg - opener->end > 100)
+ break;
+ delim_index++;
+ }
+ dest_beg = opener->end;
+ dest_end = (delim != NULL) ? delim->beg : closer->beg;
+ if(dest_end - dest_beg == 0 || dest_end - dest_beg > 100)
+ is_link = FALSE;
+
+ /* There may not be any new line in the destination. */
+ if(is_link) {
+ OFF off;
+ for(off = dest_beg; off < dest_end; off++) {
+ if(ISNEWLINE(off)) {
+ is_link = FALSE;
+ break;
+ }
+ }
+ }
+
+ if(is_link) {
+ if(delim != NULL) {
+ if(delim->end < closer->beg) {
+ opener->end = delim->beg;
+ } else {
+ /* The pipe is just before the closer: [[foo|]] */
+ closer->beg = delim->beg;
+ delim = NULL;
+ }
+ }
+
+ opener->beg = next_opener->beg;
+ opener->next = closer_index;
+ opener->flags |= MD_MARK_OPENER | MD_MARK_RESOLVED;
+
+ closer->end = next_closer->end;
+ closer->prev = opener_index;
+ closer->flags |= MD_MARK_CLOSER | MD_MARK_RESOLVED;
+
+ last_link_beg = opener->beg;
+ last_link_end = closer->end;
+
+ if(delim != NULL) {
+ delim->flags |= MD_MARK_RESOLVED;
+ md_rollback(ctx, opener_index, delim_index, MD_ROLLBACK_ALL);
+ md_analyze_link_contents(ctx, lines, n_lines, opener_index+1, closer_index);
+ } else {
+ md_rollback(ctx, opener_index, closer_index, MD_ROLLBACK_ALL);
+ }
+
+ opener_index = next_opener->prev;
+ continue;
+ }
+ }
+
if(next_opener != NULL && next_opener->beg == closer->end) {
if(next_closer->beg > closer->end + 1) {
/* Might be full reference link. */
@@ -3436,7 +3550,7 @@ md_resolve_links(MD_CTX* ctx, const MD_LINE* lines, int n_lines)
if((mark->flags & (MD_MARK_OPENER | MD_MARK_RESOLVED)) == (MD_MARK_OPENER | MD_MARK_RESOLVED)) {
if(ctx->marks[mark->next].beg >= inline_link_end) {
/* Cancel the link status. */
- if(attr.title_needs_free)
+ if(!IS_INPUT_STR(attr.title))
free(attr.title);
is_link = FALSE;
break;
@@ -3476,6 +3590,7 @@ md_resolve_links(MD_CTX* ctx, const MD_LINE* lines, int n_lines)
MD_ASSERT(ctx->marks[opener_index+2].ch == 'D');
md_mark_store_ptr(ctx, opener_index+2, attr.title);
+ /* The title might or might not have been allocated for us. */
if(attr.title_needs_free)
md_mark_chain_append(ctx, &PTR_CHAIN, opener_index+2);
ctx->marks[opener_index+2].prev = attr.title_size;
@@ -3574,8 +3689,7 @@ md_analyze_emph(MD_CTX* ctx, int mark_index)
int i, n_opener_chains;
unsigned flags = mark->flags;
- /* Apply "rule of three". (This is why we break asterisk opener
- * marks into multiple chains.) */
+ /* Apply the "rule of three". */
n_opener_chains = 0;
opener_chains[n_opener_chains++] = &ASTERISK_OPENERS_intraword_mod3_0;
if((flags & MD_MARK_EMPH_MOD3_MASK) != MD_MARK_EMPH_MOD3_2)
@@ -3611,16 +3725,17 @@ md_analyze_emph(MD_CTX* ctx, int mark_index)
if(opener != NULL) {
SZ opener_size = opener->end - opener->beg;
SZ closer_size = mark->end - mark->beg;
+ MD_MARKCHAIN* opener_chain = md_mark_chain(ctx, opener_index);
if(opener_size > closer_size) {
opener_index = md_split_emph_mark(ctx, opener_index, closer_size);
- md_mark_chain_append(ctx, md_mark_chain(ctx, opener_index), opener_index);
+ md_mark_chain_append(ctx, opener_chain, opener_index);
} else if(opener_size < closer_size) {
md_split_emph_mark(ctx, mark_index, closer_size - opener_size);
}
md_rollback(ctx, opener_index, mark_index, MD_ROLLBACK_CROSSING);
- md_resolve_range(ctx, chain, opener_index, mark_index);
+ md_resolve_range(ctx, opener_chain, opener_index, mark_index);
return;
}
}
@@ -3633,20 +3748,23 @@ md_analyze_emph(MD_CTX* ctx, int mark_index)
static void
md_analyze_tilde(MD_CTX* ctx, int mark_index)
{
- /* We attempt to be Github Flavored Markdown compatible here. GFM says
- * that length of the tilde sequence is not important at all. Note that
- * implies the TILDE_OPENERS chain can have at most one item. */
+ MD_MARK* mark = &ctx->marks[mark_index];
+ MD_MARKCHAIN* chain = md_mark_chain(ctx, mark_index);
+
+ /* We attempt to be Github Flavored Markdown compatible here. GFM accepts
+ * only tildes sequences of length 1 and 2, and the length of the opener
+ * and closer has to match. */
- if(TILDE_OPENERS.head >= 0) {
- /* The chain already contains an opener, so we may resolve the span. */
- int opener_index = TILDE_OPENERS.head;
+ if((mark->flags & MD_MARK_POTENTIAL_CLOSER) && chain->head >= 0) {
+ int opener_index = chain->head;
md_rollback(ctx, opener_index, mark_index, MD_ROLLBACK_CROSSING);
- md_resolve_range(ctx, &TILDE_OPENERS, opener_index, mark_index);
- } else {
- /* We can only be opener. */
- md_mark_chain_append(ctx, &TILDE_OPENERS, mark_index);
+ md_resolve_range(ctx, chain, opener_index, mark_index);
+ return;
}
+
+ if(mark->flags & MD_MARK_POTENTIAL_OPENER)
+ md_mark_chain_append(ctx, chain, mark_index);
}
static void
@@ -3860,8 +3978,16 @@ md_analyze_inlines(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mod
/* (1) Entities; code spans; autolinks; raw HTML. */
md_analyze_marks(ctx, lines, n_lines, 0, ctx->n_marks, _T("&"));
+ /* (2) Links. */
+ md_analyze_marks(ctx, lines, n_lines, 0, ctx->n_marks, _T("[]!"));
+ MD_CHECK(md_resolve_links(ctx, lines, n_lines));
+ BRACKET_OPENERS.head = -1;
+ BRACKET_OPENERS.tail = -1;
+ ctx->unresolved_link_head = -1;
+ ctx->unresolved_link_tail = -1;
+
if(table_mode) {
- /* (2) Analyze table cell boundaries.
+ /* (3) Analyze table cell boundaries.
* Note we reset TABLECELLBOUNDARIES chain prior to the call md_analyze_marks(),
* not after, because caller may need it. */
MD_ASSERT(n_lines == 1);
@@ -3872,14 +3998,6 @@ md_analyze_inlines(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mod
return ret;
}
- /* (3) Links. */
- md_analyze_marks(ctx, lines, n_lines, 0, ctx->n_marks, _T("[]!"));
- MD_CHECK(md_resolve_links(ctx, lines, n_lines));
- BRACKET_OPENERS.head = -1;
- BRACKET_OPENERS.tail = -1;
- ctx->unresolved_link_head = -1;
- ctx->unresolved_link_tail = -1;
-
/* (4) Emphasis and strong emphasis; permissive autolinks. */
md_analyze_link_contents(ctx, lines, n_lines, 0, ctx->n_marks);
@@ -3891,25 +4009,14 @@ static void
md_analyze_link_contents(MD_CTX* ctx, const MD_LINE* lines, int n_lines,
int mark_beg, int mark_end)
{
+ int i;
+
md_analyze_marks(ctx, lines, n_lines, mark_beg, mark_end, _T("*_~$@:."));
- ASTERISK_OPENERS_extraword_mod3_0.head = -1;
- ASTERISK_OPENERS_extraword_mod3_0.tail = -1;
- ASTERISK_OPENERS_extraword_mod3_1.head = -1;
- ASTERISK_OPENERS_extraword_mod3_1.tail = -1;
- ASTERISK_OPENERS_extraword_mod3_2.head = -1;
- ASTERISK_OPENERS_extraword_mod3_2.tail = -1;
- ASTERISK_OPENERS_intraword_mod3_0.head = -1;
- ASTERISK_OPENERS_intraword_mod3_0.tail = -1;
- ASTERISK_OPENERS_intraword_mod3_1.head = -1;
- ASTERISK_OPENERS_intraword_mod3_1.tail = -1;
- ASTERISK_OPENERS_intraword_mod3_2.head = -1;
- ASTERISK_OPENERS_intraword_mod3_2.tail = -1;
- UNDERSCORE_OPENERS.head = -1;
- UNDERSCORE_OPENERS.tail = -1;
- TILDE_OPENERS.head = -1;
- TILDE_OPENERS.tail = -1;
- DOLLAR_OPENERS.head = -1;
- DOLLAR_OPENERS.tail = -1;
+
+ for(i = OPENERS_CHAIN_FIRST; i <= OPENERS_CHAIN_LAST; i++) {
+ ctx->mark_chains[i].head = -1;
+ ctx->mark_chains[i].tail = -1;
+ }
}
static int
@@ -3941,6 +4048,27 @@ abort:
return ret;
}
+static int
+md_enter_leave_span_wikilink(MD_CTX* ctx, int enter, const CHAR* target, SZ target_size)
+{
+ MD_ATTRIBUTE_BUILD target_build = { 0 };
+ MD_SPAN_WIKILINK_DETAIL det;
+ int ret = 0;
+
+ memset(&det, 0, sizeof(MD_SPAN_WIKILINK_DETAIL));
+ MD_CHECK(md_build_attribute(ctx, target, target_size, 0, &det.target, &target_build));
+
+ if (enter)
+ MD_ENTER_SPAN(MD_SPAN_WIKILINK, &det);
+ else
+ MD_LEAVE_SPAN(MD_SPAN_WIKILINK, &det);
+
+abort:
+ md_free_attribute(ctx, &target_build);
+ return ret;
+}
+
+
/* Render the output, accordingly to the analyzed ctx->marks. */
static int
md_process_inlines(MD_CTX* ctx, const MD_LINE* lines, int n_lines)
@@ -3996,7 +4124,23 @@ md_process_inlines(MD_CTX* ctx, const MD_LINE* lines, int n_lines)
}
break;
- case '_':
+ case '_': /* Underline (or emphasis if we fall through). */
+ if(ctx->parser.flags & MD_FLAG_UNDERLINE) {
+ if(mark->flags & MD_MARK_OPENER) {
+ while(off < mark->end) {
+ MD_ENTER_SPAN(MD_SPAN_U, NULL);
+ off++;
+ }
+ } else {
+ while(off < mark->end) {
+ MD_LEAVE_SPAN(MD_SPAN_U, NULL);
+ off++;
+ }
+ }
+ break;
+ }
+ /* Fall though. */
+
case '*': /* Emphasis, strong emphasis. */
if(mark->flags & MD_MARK_OPENER) {
if((mark->end - off) % 2) {
@@ -4036,15 +4180,37 @@ md_process_inlines(MD_CTX* ctx, const MD_LINE* lines, int n_lines)
}
break;
- case '[': /* Link, image. */
+ case '[': /* Link, wiki link, image. */
case '!':
case ']':
{
const MD_MARK* opener = (mark->ch != ']' ? mark : &ctx->marks[mark->prev]);
- const MD_MARK* dest_mark = opener+1;
- const MD_MARK* title_mark = opener+2;
+ const MD_MARK* closer = &ctx->marks[opener->next];
+ const MD_MARK* dest_mark;
+ const MD_MARK* title_mark;
+
+ if ((opener->ch == '[' && closer->ch == ']') &&
+ opener->end - opener->beg >= 2 &&
+ closer->end - closer->beg >= 2)
+ {
+ int has_label = (opener->end - opener->beg > 2);
+ SZ target_sz;
+
+ if(has_label)
+ target_sz = opener->end - (opener->beg+2);
+ else
+ target_sz = closer->beg - opener->end;
+ MD_CHECK(md_enter_leave_span_wikilink(ctx, (mark->ch != ']'),
+ has_label ? STR(opener->beg+2) : STR(opener->end),
+ target_sz));
+
+ break;
+ }
+
+ dest_mark = opener+1;
MD_ASSERT(dest_mark->ch == 'D');
+ title_mark = opener+2;
MD_ASSERT(title_mark->ch == 'D');
MD_CHECK(md_enter_leave_span_a(ctx, (mark->ch != ']'),
@@ -4251,7 +4417,7 @@ md_process_table_row(MD_CTX* ctx, MD_BLOCKTYPE cell_type, OFF beg, OFF end,
{
MD_LINE line;
OFF* pipe_offs = NULL;
- int i, j, n;
+ int i, j, k, n;
int ret = 0;
line.beg = beg;
@@ -4263,32 +4429,32 @@ md_process_table_row(MD_CTX* ctx, MD_BLOCKTYPE cell_type, OFF beg, OFF end,
/* We have to remember the cell boundaries in local buffer because
* ctx->marks[] shall be reused during cell contents processing. */
- n = ctx->n_table_cell_boundaries;
+ n = ctx->n_table_cell_boundaries + 2;
pipe_offs = (OFF*) malloc(n * sizeof(OFF));
if(pipe_offs == NULL) {
MD_LOG("malloc() failed.");
ret = -1;
goto abort;
}
- for(i = TABLECELLBOUNDARIES.head, j = 0; i >= 0; i = ctx->marks[i].next) {
+ j = 0;
+ pipe_offs[j++] = beg;
+ for(i = TABLECELLBOUNDARIES.head; i >= 0; i = ctx->marks[i].next) {
MD_MARK* mark = &ctx->marks[i];
- pipe_offs[j++] = mark->beg;
+ pipe_offs[j++] = mark->end;
}
+ pipe_offs[j++] = end+1;
/* Process cells. */
MD_ENTER_BLOCK(MD_BLOCK_TR, NULL);
- j = 0;
- if(beg < pipe_offs[0] && j < col_count)
- MD_CHECK(md_process_table_cell(ctx, cell_type, align[j++], beg, pipe_offs[0]));
- for(i = 0; i < n-1 && j < col_count; i++)
- MD_CHECK(md_process_table_cell(ctx, cell_type, align[j++], pipe_offs[i]+1, pipe_offs[i+1]));
- if(pipe_offs[n-1] < end-1 && j < col_count)
- MD_CHECK(md_process_table_cell(ctx, cell_type, align[j++], pipe_offs[n-1]+1, end));
+ k = 0;
+ for(i = 0; i < j-1 && k < col_count; i++) {
+ if(pipe_offs[i] < pipe_offs[i+1]-1)
+ MD_CHECK(md_process_table_cell(ctx, cell_type, align[k++], pipe_offs[i], pipe_offs[i+1]-1));
+ }
/* Make sure we call enough table cells even if the current table contains
* too few of them. */
- while(j < col_count)
- MD_CHECK(md_process_table_cell(ctx, cell_type, align[j++], 0, 0));
-
+ while(k < col_count)
+ MD_CHECK(md_process_table_cell(ctx, cell_type, align[k++], 0, 0));
MD_LEAVE_BLOCK(MD_BLOCK_TR, NULL);
abort:
@@ -4340,38 +4506,6 @@ abort:
return ret;
}
-static int
-md_is_table_row(MD_CTX* ctx, OFF beg, OFF* p_end)
-{
- MD_LINE line;
- int i;
- int ret = FALSE;
-
- line.beg = beg;
- line.end = beg;
-
- /* Find end of line. */
- while(line.end < ctx->size && !ISNEWLINE(line.end))
- line.end++;
-
- MD_CHECK(md_analyze_inlines(ctx, &line, 1, TRUE));
-
- if(TABLECELLBOUNDARIES.head >= 0) {
- if(p_end != NULL)
- *p_end = line.end;
- ret = TRUE;
- }
-
-abort:
- /* Free any temporary memory blocks stored within some dummy marks. */
- for(i = PTR_CHAIN.head; i >= 0; i = ctx->marks[i].next)
- free(md_mark_get_ptr(ctx, i));
- PTR_CHAIN.head = -1;
- PTR_CHAIN.tail = -1;
-
- return ret;
-}
-
/**************************
*** Processing Block ***
@@ -4704,7 +4838,9 @@ md_push_block_bytes(MD_CTX* ctx, int n_bytes)
if(ctx->n_block_bytes + n_bytes > ctx->alloc_block_bytes) {
void* new_block_bytes;
- ctx->alloc_block_bytes = (ctx->alloc_block_bytes > 0 ? ctx->alloc_block_bytes * 2 : 512);
+ ctx->alloc_block_bytes = (ctx->alloc_block_bytes > 0
+ ? ctx->alloc_block_bytes + ctx->alloc_block_bytes / 2
+ : 512);
new_block_bytes = realloc(ctx->block_bytes, ctx->alloc_block_bytes);
if(new_block_bytes == NULL) {
MD_LOG("realloc() failed.");
@@ -5136,7 +5272,7 @@ md_is_html_block_start_condition(MD_CTX* ctx, OFF beg)
#ifdef X
#undef X
#endif
-#define X(name) { _T(name), sizeof(name)-1 }
+#define X(name) { _T(name), (sizeof(name)-1) / sizeof(CHAR) }
#define Xend { NULL, 0 }
static const TAG t1[] = { X("script"), X("pre"), X("style"), Xend };
@@ -5192,7 +5328,7 @@ md_is_html_block_start_condition(MD_CTX* ctx, OFF beg)
/* Check for type 5: <![CDATA[ */
if(off + 8 < ctx->size) {
- if(md_ascii_eq(STR(off), _T("![CDATA["), 8 * sizeof(CHAR)))
+ if(md_ascii_eq(STR(off), _T("![CDATA["), 8))
return 5;
}
}
@@ -5341,7 +5477,9 @@ md_push_container(MD_CTX* ctx, const MD_CONTAINER* container)
if(ctx->n_containers >= ctx->alloc_containers) {
MD_CONTAINER* new_containers;
- ctx->alloc_containers = (ctx->alloc_containers > 0 ? ctx->alloc_containers * 2 : 16);
+ ctx->alloc_containers = (ctx->alloc_containers > 0
+ ? ctx->alloc_containers + ctx->alloc_containers / 2
+ : 16);
new_containers = realloc(ctx->containers, ctx->alloc_containers * sizeof(MD_CONTAINER));
if(new_containers == NULL) {
MD_LOG("realloc() failed.");
@@ -5561,6 +5699,7 @@ md_analyze_line(MD_CTX* ctx, OFF beg, OFF* p_end,
line->indent--;
line->beg = off;
+
} else if(c->ch != _T('>') && line->indent >= c->contents_indent) {
/* List. */
line->indent -= c->contents_indent;
@@ -5803,9 +5942,7 @@ md_analyze_line(MD_CTX* ctx, OFF beg, OFF* p_end,
}
/* Check whether we are table continuation. */
- if(pivot_line->type == MD_LINE_TABLE && md_is_table_row(ctx, off, &off) &&
- n_parents == ctx->n_containers)
- {
+ if(pivot_line->type == MD_LINE_TABLE && n_parents == ctx->n_containers) {
line->type = MD_LINE_TABLE;
break;
}
@@ -5859,8 +5996,7 @@ md_analyze_line(MD_CTX* ctx, OFF beg, OFF* p_end,
unsigned col_count;
if(ctx->current_block != NULL && ctx->current_block->n_lines == 1 &&
- md_is_table_underline(ctx, off, &off, &col_count) &&
- md_is_table_row(ctx, pivot_line->beg, NULL))
+ md_is_table_underline(ctx, off, &off, &col_count))
{
line->data = col_count;
line->type = MD_LINE_TABLEUNDERLINE;
diff --git a/src/3rdparty/md4c/md4c.h b/src/3rdparty/md4c/md4c.h
index 6d9fce5180..c2c4311f50 100644
--- a/src/3rdparty/md4c/md4c.h
+++ b/src/3rdparty/md4c/md4c.h
@@ -2,7 +2,7 @@
* MD4C: Markdown parser for C
* (http://github.com/mity/md4c)
*
- * Copyright (c) 2016-2019 Martin Mitas
+ * Copyright (c) 2016-2020 Martin Mitas
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -135,7 +135,16 @@ typedef enum MD_SPANTYPE {
* Note: Recognized only when MD_FLAG_LATEXMATHSPANS is enabled.
*/
MD_SPAN_LATEXMATH,
- MD_SPAN_LATEXMATH_DISPLAY
+ MD_SPAN_LATEXMATH_DISPLAY,
+
+ /* Wiki links
+ * Note: Recognized only when MD_FLAG_WIKILINKS is enabled.
+ */
+ MD_SPAN_WIKILINK,
+
+ /* <u>...</u>
+ * Note: Recognized only when MD_FLAG_UNDERLINE is enabled. */
+ MD_SPAN_U
} MD_SPANTYPE;
/* Text is the actual textual contents of span. */
@@ -268,6 +277,10 @@ typedef struct MD_SPAN_IMG_DETAIL {
MD_ATTRIBUTE title;
} MD_SPAN_IMG_DETAIL;
+/* Detailed info for MD_SPAN_WIKILINK. */
+typedef struct MD_SPAN_WIKILINK {
+ MD_ATTRIBUTE target;
+} MD_SPAN_WIKILINK_DETAIL;
/* Flags specifying extensions/deviations from CommonMark specification.
*
@@ -286,6 +299,8 @@ typedef struct MD_SPAN_IMG_DETAIL {
#define MD_FLAG_PERMISSIVEWWWAUTOLINKS 0x0400 /* Enable WWW autolinks (even without any scheme prefix, if they begin with 'www.') */
#define MD_FLAG_TASKLISTS 0x0800 /* Enable task list extension. */
#define MD_FLAG_LATEXMATHSPANS 0x1000 /* Enable $ and $$ containing LaTeX equations. */
+#define MD_FLAG_WIKILINKS 0x2000 /* Enable wiki links extension. */
+#define MD_FLAG_UNDERLINE 0x4000 /* Enable underline extension (and disables '_' for normal emphasis). */
#define MD_FLAG_PERMISSIVEAUTOLINKS (MD_FLAG_PERMISSIVEEMAILAUTOLINKS | MD_FLAG_PERMISSIVEURLAUTOLINKS | MD_FLAG_PERMISSIVEWWWAUTOLINKS)
#define MD_FLAG_NOHTML (MD_FLAG_NOHTMLBLOCKS | MD_FLAG_NOHTMLSPANS)
diff --git a/src/3rdparty/md4c/qt_attribution.json b/src/3rdparty/md4c/qt_attribution.json
index 5fd77269e9..c574b97711 100644
--- a/src/3rdparty/md4c/qt_attribution.json
+++ b/src/3rdparty/md4c/qt_attribution.json
@@ -9,7 +9,7 @@
"License": "MIT License",
"LicenseId": "MIT",
"LicenseFile": "LICENSE.md",
- "Version": "0.3.4",
- "DownloadLocation": "https://github.com/mity/md4c/releases/tag/release-0.3.4",
- "Copyright": "Copyright © 2016-2019 Martin Mitáš"
+ "Version": "0.4.3",
+ "DownloadLocation": "https://github.com/mity/md4c/releases/tag/release-0.4.3",
+ "Copyright": "Copyright © 2016-2020 Martin Mitáš"
}
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
index c1c4d5559d..87d326e225 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
@@ -47,11 +47,13 @@ import java.util.concurrent.Semaphore;
import android.app.Activity;
import android.app.Service;
+import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.ContentResolver;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ActivityInfo;
+import android.content.UriPermission;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
@@ -73,6 +75,7 @@ import java.lang.reflect.Method;
import java.security.KeyStore;
import java.security.cert.X509Certificate;
import java.util.Iterator;
+import java.util.List;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
@@ -152,35 +155,79 @@ public class QtNative
}
}
- public static boolean openURL(String url, String mime)
+ private static Uri getUriWithValidPermission(Context context, String uri, String openMode)
{
- boolean ok = true;
+ try {
+ List<UriPermission> permissions = context.getContentResolver().getPersistedUriPermissions();
+ String uriStr = Uri.parse(uri).getPath();
+
+ for (int i = 0; i < permissions.size(); ++i) {
+ Uri iterUri = permissions.get(i).getUri();
+ boolean isRightPermission = permissions.get(i).isReadPermission();
+
+ if (!openMode.equals("r"))
+ isRightPermission = permissions.get(i).isWritePermission();
+
+ if (iterUri.getPath().equals(uriStr) && isRightPermission)
+ return iterUri;
+ }
+
+ return null;
+ } catch (SecurityException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ public static boolean openURL(Context context, String url, String mime)
+ {
+ Uri uri = getUriWithValidPermission(context, url, "r");
+
+ if (uri == null) {
+ Log.e(QtTAG, "openURL(): No permissions to open Uri");
+ return false;
+ }
try {
- Uri uri = Uri.parse(url);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
+ intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
if (!mime.isEmpty())
intent.setDataAndType(uri, mime);
+
activity().startActivity(intent);
- } catch (Exception e) {
+
+ return true;
+ } catch (IllegalArgumentException e) {
+ Log.e(QtTAG, "openURL(): Invalid Uri");
+ return false;
+ } catch (UnsupportedOperationException e) {
+ Log.e(QtTAG, "openURL(): Unsupported operation for given Uri");
+ return false;
+ } catch (ActivityNotFoundException e) {
e.printStackTrace();
- ok = false;
+ return false;
}
-
- return ok;
}
public static int openFdForContentUrl(Context context, String contentUrl, String openMode)
{
+ Uri uri = getUriWithValidPermission(context, contentUrl, openMode);
+ int error = -1;
+
+ if (uri == null) {
+ Log.e(QtTAG, "openFdForContentUrl(): No permissions to open Uri");
+ return error;
+ }
+
try {
ContentResolver resolver = context.getContentResolver();
- ParcelFileDescriptor fdDesc = resolver.openFileDescriptor(Uri.parse(contentUrl), openMode);
+ ParcelFileDescriptor fdDesc = resolver.openFileDescriptor(uri, openMode);
return fdDesc.detachFd();
} catch (FileNotFoundException e) {
- return -1;
- } catch (SecurityException e) {
- Log.e(QtTAG, "Exception when opening file", e);
- return -1;
+ return error;
+ } catch (IllegalArgumentException e) {
+ Log.e(QtTAG, "openFdForContentUrl(): Invalid Uri");
+ return error;
}
}
diff --git a/src/corelib/codecs/qutfcodec.cpp b/src/corelib/codecs/qutfcodec.cpp
index af36bd7e2f..8561f908b9 100644
--- a/src/corelib/codecs/qutfcodec.cpp
+++ b/src/corelib/codecs/qutfcodec.cpp
@@ -930,6 +930,7 @@ QString QUtf32::convertToUnicode(const char *chars, int len, QTextCodec::Convert
tuple[num++] = *chars++;
if (num == 4) {
if (!headerdone) {
+ headerdone = true;
if (endian == DetectEndianness) {
if (tuple[0] == 0xff && tuple[1] == 0xfe && tuple[2] == 0 && tuple[3] == 0 && endian != BigEndianness) {
endian = LittleEndianness;
diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h
index 57ccd308d7..8851e08d4f 100644
--- a/src/corelib/global/qnamespace.h
+++ b/src/corelib/global/qnamespace.h
@@ -505,7 +505,7 @@ namespace Qt {
AA_DontUseNativeMenuBar = 6,
AA_MacDontSwapCtrlAndMeta = 7,
AA_Use96Dpi = 8,
- AA_MSWindowsDisableVirtualKeyboard = 9,
+ AA_DisableNativeVirtualKeyboard = 9,
#if QT_DEPRECATED_SINCE(5, 14)
AA_X11InitThreads Q_DECL_ENUMERATOR_DEPRECATED = 10,
#endif
diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
index 708ecb11ab..3e22c9e661 100644
--- a/src/corelib/global/qnamespace.qdoc
+++ b/src/corelib/global/qnamespace.qdoc
@@ -293,10 +293,10 @@
This attribute must be set before QGuiApplication is constructed.
This value was added in 5.13
- \value AA_MSWindowsDisableVirtualKeyboard When this attribute is set,
- Windows' native on-screen virtual keyboard will not be shown
- automatically when a text input widget gains focus on a system
- without a physical keyboard.
+ \value AA_DisableNativeVirtualKeyboard When this attribute is set, the native
+ on-screen virtual keyboard will not be shown automatically when a
+ text input widget gains focus on a system without a physical keyboard.
+ Currently supported on the Windows platform only.
This value was added in 5.15
The following values are deprecated or obsolete:
@@ -3339,6 +3339,8 @@
This is a dummy type, designed to help users transition from certain deprecated APIs to their replacement APIs.
+ \omitvalue ReturnByValue
+
\sa QCursor::bitmap()
\sa QCursor::mask()
\sa QLabel::picture()
diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp
index 5d5b0b2a29..acc60915e7 100644
--- a/src/corelib/io/qprocess.cpp
+++ b/src/corelib/io/qprocess.cpp
@@ -2230,8 +2230,16 @@ void QProcessPrivate::start(QIODevice::OpenMode mode)
startProcess();
}
+/*!
+ \since 5.15
+
+ Splits the string \a command into a list of tokens, and returns
+ the list.
-static QStringList parseCombinedArgString(const QString &program)
+ Tokens with spaces can be surrounded by double quotes; three
+ consecutive double quotes represent the quote character itself.
+*/
+QStringList QProcess::splitCommand(const QString &command)
{
QStringList args;
QString tmp;
@@ -2241,13 +2249,13 @@ static QStringList parseCombinedArgString(const QString &program)
// handle quoting. tokens can be surrounded by double quotes
// "hello world". three consecutive double quotes represent
// the quote character itself.
- for (int i = 0; i < program.size(); ++i) {
- if (program.at(i) == QLatin1Char('"')) {
+ for (int i = 0; i < command.size(); ++i) {
+ if (command.at(i) == QLatin1Char('"')) {
++quoteCount;
if (quoteCount == 3) {
// third consecutive quote
quoteCount = 0;
- tmp += program.at(i);
+ tmp += command.at(i);
}
continue;
}
@@ -2256,13 +2264,13 @@ static QStringList parseCombinedArgString(const QString &program)
inQuote = !inQuote;
quoteCount = 0;
}
- if (!inQuote && program.at(i).isSpace()) {
+ if (!inQuote && command.at(i).isSpace()) {
if (!tmp.isEmpty()) {
args += tmp;
tmp.clear();
}
} else {
- tmp += program.at(i);
+ tmp += command.at(i);
}
}
if (!tmp.isEmpty())
@@ -2272,6 +2280,7 @@ static QStringList parseCombinedArgString(const QString &program)
}
/*!
+ \obsolete
\overload
Starts the command \a command in a new process.
@@ -2308,11 +2317,13 @@ static QStringList parseCombinedArgString(const QString &program)
list-based API. In these rare cases you need to use setProgram() and
setNativeArguments() instead of this function.
+ \sa splitCommand()
+
*/
#if !defined(QT_NO_PROCESS_COMBINED_ARGUMENT_START)
void QProcess::start(const QString &command, OpenMode mode)
{
- QStringList args = parseCombinedArgString(command);
+ QStringList args = splitCommand(command);
if (args.isEmpty()) {
Q_D(QProcess);
d->setErrorAndEmit(QProcess::FailedToStart, tr("No program defined"));
@@ -2477,6 +2488,7 @@ int QProcess::execute(const QString &program, const QStringList &arguments)
}
/*!
+ \obsolete
\overload
Starts the program \a command in a new process, waits for it to finish,
@@ -2487,7 +2499,7 @@ int QProcess::execute(const QString &program, const QStringList &arguments)
After the \a command string has been split and unquoted, this function
behaves like the overload which takes the arguments as a string list.
- \sa start()
+ \sa start(), splitCommand()
*/
int QProcess::execute(const QString &command)
{
@@ -2543,6 +2555,7 @@ bool QProcess::startDetached(const QString &program,
}
/*!
+ \obsolete
\overload startDetached()
Starts the command \a command in a new process, and detaches from it.
@@ -2553,11 +2566,11 @@ bool QProcess::startDetached(const QString &program,
After the \a command string has been split and unquoted, this function
behaves like the overload which takes the arguments as a string list.
- \sa start(const QString &command, QIODevice::OpenMode mode)
+ \sa start(const QString &command, QIODevice::OpenMode mode), splitCommand()
*/
bool QProcess::startDetached(const QString &command)
{
- QStringList args = parseCombinedArgString(command);
+ QStringList args = splitCommand(command);
if (args.isEmpty())
return false;
diff --git a/src/corelib/io/qprocess.h b/src/corelib/io/qprocess.h
index 0a2187750f..0ef02b196d 100644
--- a/src/corelib/io/qprocess.h
+++ b/src/corelib/io/qprocess.h
@@ -160,8 +160,14 @@ public:
void start(const QString &program, const QStringList &arguments, OpenMode mode = ReadWrite);
#if !defined(QT_NO_PROCESS_COMBINED_ARGUMENT_START)
+#if QT_DEPRECATED_SINCE(5, 15)
+ QT_DEPRECATED_X(
+ "Use QProcess::start(const QString &program, const QStringList &arguments,"
+ "OpenMode mode = ReadWrite) instead"
+ )
void start(const QString &command, OpenMode mode = ReadWrite);
#endif
+#endif
void start(OpenMode mode = ReadWrite);
bool startDetached(qint64 *pid = nullptr);
bool open(OpenMode mode = ReadWrite) override;
@@ -250,8 +256,12 @@ public:
bool atEnd() const override; // ### Qt6: remove trivial override
static int execute(const QString &program, const QStringList &arguments);
+#if QT_DEPRECATED_SINCE(5, 15)
+ QT_DEPRECATED_X(
+ "Use QProcess::execute(const QString &program, const QStringList &arguments) instead"
+ )
static int execute(const QString &command);
-
+#endif
static bool startDetached(const QString &program, const QStringList &arguments,
const QString &workingDirectory
#if defined(Q_QDOC)
@@ -261,12 +271,19 @@ public:
#if !defined(Q_QDOC)
static bool startDetached(const QString &program, const QStringList &arguments); // ### Qt6: merge overloads
#endif
+#if QT_DEPRECATED_SINCE(5, 15)
+ QT_DEPRECATED_X(
+ "Use QProcess::startDetached(const QString &program, const QStringList &arguments) instead"
+ )
static bool startDetached(const QString &command);
+#endif
static QStringList systemEnvironment();
static QString nullDevice();
+ static QStringList splitCommand(const QString &command);
+
public Q_SLOTS:
void terminate();
void kill();
diff --git a/src/corelib/io/qstandardpaths.cpp b/src/corelib/io/qstandardpaths.cpp
index a5128a868b..9d773e6f52 100644
--- a/src/corelib/io/qstandardpaths.cpp
+++ b/src/corelib/io/qstandardpaths.cpp
@@ -343,7 +343,10 @@ QT_BEGIN_NAMESPACE
OS configuration, locale, or they may change in future Qt versions.
\note On Android, applications with open files on the external storage (<USER> locations),
- will be killed if the external storage is unmounted.
+ will be killed if the external storage is unmounted.
+
+ \note On Android 6.0 (API 23) or higher, the "WRITE_EXTERNAL_STORAGE" permission must be
+ requested at runtime when using QStandardPaths::writableLocation or QStandardPaths::standardLocations.
\note On Android, reading/writing to GenericDataLocation needs the READ_EXTERNAL_STORAGE/WRITE_EXTERNAL_STORAGE permission granted.
diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp
index b6ddcce27c..3e7d8e113c 100644
--- a/src/corelib/io/qurl.cpp
+++ b/src/corelib/io/qurl.cpp
@@ -4149,7 +4149,7 @@ static bool isIp6(const QString &text)
/*!
Returns a valid URL from a user supplied \a userInput string if one can be
- deducted. In the case that is not possible, an invalid QUrl() is returned.
+ deduced. In the case that is not possible, an invalid QUrl() is returned.
This overload takes a \a workingDirectory path, in order to be able to
handle relative paths. This is especially useful when handling command
diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.cpp b/src/corelib/itemmodels/qsortfilterproxymodel.cpp
index 033e4e2f97..e0506b12db 100644
--- a/src/corelib/itemmodels/qsortfilterproxymodel.cpp
+++ b/src/corelib/itemmodels/qsortfilterproxymodel.cpp
@@ -3056,12 +3056,8 @@ bool QSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &
Returns \c true if the item in the column indicated by the given \a source_column
and \a source_parent should be included in the model; otherwise returns \c false.
- The default implementation returns \c true if the value held by the relevant item
- matches the filter string, wildcard string or regular expression.
-
- \note By default, the Qt::DisplayRole is used to determine if the column
- should be accepted or not. This can be changed by setting the \l
- filterRole property.
+ \note The default implementation always returns \c true. You must reimplement this
+ method to get the described behavior.
\sa filterAcceptsRow(), setFilterFixedString(), setFilterRegExp(), setFilterWildcard()
*/
diff --git a/src/corelib/kernel/qmath.qdoc b/src/corelib/kernel/qmath.qdoc
index a2e24e925b..346171f044 100644
--- a/src/corelib/kernel/qmath.qdoc
+++ b/src/corelib/kernel/qmath.qdoc
@@ -51,8 +51,6 @@
\value M_2_SQRTPI Two divided by the square root of pi, 2 / \unicode{0x221A}\unicode{0x3C0}
\value M_SQRT2 The square root of two, \unicode{0x221A}2
\value M_SQRT1_2 The square roof of half, 1 / \unicode{0x221A}2
-
- \pagekeywords math trigonometry qmath floor ceiling absolute sine cosine tangent inverse tan exponent power natural logarithm pi
*/
/*!
diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp
index 0730dbffd1..4c1f9f20f7 100644
--- a/src/corelib/kernel/qmetatype.cpp
+++ b/src/corelib/kernel/qmetatype.cpp
@@ -714,7 +714,7 @@ QMetaType &QMetaType::operator=(const QMetaType &other)
as the QMetaType \a b, otherwise returns \c false.
*/
-/*! \fn bool operator!=(const QMetaType &a, const QMetaType &c)
+/*! \fn bool operator!=(const QMetaType &a, const QMetaType &b)
\since 5.15
\relates QMetaType
\overload
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index 697c9b6148..2fdf94c38b 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -47,6 +47,7 @@
#include "qabstracteventdispatcher_p.h"
#include "qcoreapplication.h"
#include "qcoreapplication_p.h"
+#include "qloggingcategory.h"
#include "qvariant.h"
#include "qmetaobject.h"
#include <qregexp.h>
@@ -78,6 +79,8 @@ QT_BEGIN_NAMESPACE
static int DIRECT_CONNECTION_ONLY = 0;
+Q_LOGGING_CATEGORY(lcConnections, "qt.core.qmetaobject.connectslotsbyname")
+
Q_CORE_EXPORT QBasicAtomicPointer<QSignalSpyCallbackSet> qt_signal_spy_callback_set = Q_BASIC_ATOMIC_INITIALIZER(nullptr);
void qt_register_signal_spy_callbacks(QSignalSpyCallbackSet *callback_set)
@@ -183,15 +186,7 @@ QMetaObject *QObjectData::dynamicMetaObject() const
QObjectPrivate::QObjectPrivate(int version)
: threadData(nullptr), currentChildBeingDeleted(nullptr)
{
-#ifdef QT_BUILD_INTERNAL
- // Don't check the version parameter in internal builds.
- // This allows incompatible versions to be loaded, possibly for testing.
- Q_UNUSED(version);
-#else
- if (Q_UNLIKELY(version != QObjectPrivateVersion))
- qFatal("Cannot mix incompatible Qt library (version 0x%x) with this library (version 0x%x)",
- version, QObjectPrivateVersion);
-#endif
+ checkForIncompatibleLibraryVersion(version);
// QObjectData initialization
q_ptr = nullptr;
@@ -3555,6 +3550,37 @@ bool QMetaObjectPrivate::disconnect(const QObject *sender,
return success;
}
+// Helpers for formatting the connect statements of connectSlotsByName()'s debug mode
+static QByteArray formatConnectionSignature(const char *className, const QMetaMethod &method)
+{
+ const auto signature = method.methodSignature();
+ Q_ASSERT(signature.endsWith(')'));
+ const int openParen = signature.indexOf('(');
+ const bool hasParameters = openParen >= 0 && openParen < signature.size() - 2;
+ QByteArray result;
+ if (hasParameters) {
+ result += "qOverload<"
+ + signature.mid(openParen + 1, signature.size() - openParen - 2) + ">(";
+ }
+ result += '&';
+ result += className + QByteArrayLiteral("::") + method.name();
+ if (hasParameters)
+ result += ')';
+ return result;
+}
+
+static QByteArray msgConnect(const QMetaObject *senderMo, const QByteArray &senderName,
+ const QMetaMethod &signal, const QObject *receiver, int receiverIndex)
+{
+ const auto receiverMo = receiver->metaObject();
+ const auto slot = receiverMo->method(receiverIndex);
+ QByteArray message = QByteArrayLiteral("QObject::connect(")
+ + senderName + ", " + formatConnectionSignature(senderMo->className(), signal)
+ + ", " + receiver->objectName().toLatin1() + ", "
+ + formatConnectionSignature(receiverMo->className(), slot) + ");";
+ return message;
+}
+
/*!
\fn void QMetaObject::connectSlotsByName(QObject *object)
@@ -3636,6 +3662,8 @@ void QMetaObject::connectSlotsByName(QObject *o)
// we connect it...
if (Connection(QMetaObjectPrivate::connect(co, sigIndex, smeta, o, i))) {
foundIt = true;
+ qCDebug(lcConnections, "%s",
+ msgConnect(smeta, coName, QMetaObjectPrivate::signal(smeta, sigIndex), o, i).constData());
// ...and stop looking for further objects with the same name.
// Note: the Designer will make sure each object name is unique in the above
// 'list' but other code may create two child objects with the same name. In
diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h
index d6e73fbefc..97b492360c 100644
--- a/src/corelib/kernel/qobject_p.h
+++ b/src/corelib/kernel/qobject_p.h
@@ -310,6 +310,8 @@ public:
virtual ~QObjectPrivate();
void deleteChildren();
+ inline void checkForIncompatibleLibraryVersion(int version) const;
+
void setParent_helper(QObject *);
void moveToThread_helper();
void setThreadData_helper(QThreadData *currentData, QThreadData *targetData);
@@ -384,6 +386,28 @@ public:
Q_DECLARE_TYPEINFO(QObjectPrivate::ConnectionList, Q_MOVABLE_TYPE);
+/*
+ Catch mixing of incompatible library versions.
+
+ Should be called from the constructor of every non-final subclass
+ of QObjectPrivate, to ensure we catch incompatibilities between
+ the intermediate base and subclasses thereof.
+*/
+inline void QObjectPrivate::checkForIncompatibleLibraryVersion(int version) const
+{
+#if defined(QT_BUILD_INTERNAL)
+ // Don't check the version parameter in internal builds.
+ // This allows incompatible versions to be loaded, possibly for testing.
+ Q_UNUSED(version);
+#else
+ if (Q_UNLIKELY(version != QObjectPrivateVersion)) {
+ qFatal("Cannot mix incompatible Qt library (%d.%d.%d) with this library (%d.%d.%d)",
+ (version >> 16) & 0xff, (version >> 8) & 0xff, version & 0xff,
+ (QObjectPrivateVersion >> 16) & 0xff, (QObjectPrivateVersion >> 8) & 0xff, QObjectPrivateVersion & 0xff);
+ }
+#endif
+}
+
inline bool QObjectPrivate::isDeclarativeSignalConnected(uint signal_index) const
{
return declarativeData && QAbstractDeclarativeData::isSignalConnected
diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h
index b84b5a503f..fd7c081e88 100644
--- a/src/corelib/kernel/qobjectdefs.h
+++ b/src/corelib/kernel/qobjectdefs.h
@@ -356,7 +356,7 @@ struct Q_CORE_EXPORT QMetaObject
static typename std::enable_if<!QtPrivate::FunctionPointer<Func>::IsPointerToMemberFunction
&& QtPrivate::FunctionPointer<Func>::ArgumentCount == -1
&& !std::is_convertible<Func, const char*>::value, bool>::type
- invokeMethod(QObject *context, Func function, typename std::result_of<Func()>::type *ret)
+ invokeMethod(QObject *context, Func function, decltype(function()) *ret)
{
return invokeMethodImpl(context,
new QtPrivate::QFunctorSlotObjectWithNoArgs<Func, decltype(function())>(std::move(function)),
diff --git a/src/corelib/serialization/qcborcommon.cpp b/src/corelib/serialization/qcborcommon.cpp
index 37fb198744..5fc47fa399 100644
--- a/src/corelib/serialization/qcborcommon.cpp
+++ b/src/corelib/serialization/qcborcommon.cpp
@@ -54,6 +54,8 @@ QT_BEGIN_NAMESPACE
\brief The <QtCborCommon> header contains definitions common to both the
streaming classes (QCborStreamReader and QCborStreamWriter) and to
QCborValue.
+
+ \sa QCborError
*/
/*!
@@ -203,7 +205,7 @@ QDataStream &operator>>(QDataStream &ds, QCborSimpleType &st)
/*!
\class QCborError
\inmodule QtCore
- \relates <QtCborCommon>
+ \inheaderfile <QtCborCommon>
\reentrant
\since 5.12
diff --git a/src/corelib/text/qharfbuzz.cpp b/src/corelib/text/qharfbuzz.cpp
index a3e266ccd2..f54ce26206 100644
--- a/src/corelib/text/qharfbuzz.cpp
+++ b/src/corelib/text/qharfbuzz.cpp
@@ -72,7 +72,7 @@ HB_UChar16 HB_GetMirroredChar(HB_UChar16 ch)
void (*HB_Library_Resolve(const char *library, int version, const char *symbol))()
{
-#if !QT_CONFIG(library)
+#if !QT_CONFIG(library) || defined(Q_OS_WASM)
Q_UNUSED(library);
Q_UNUSED(version);
Q_UNUSED(symbol);
diff --git a/src/corelib/text/qstring.cpp b/src/corelib/text/qstring.cpp
index 877f5df462..8cdf41ffbf 100644
--- a/src/corelib/text/qstring.cpp
+++ b/src/corelib/text/qstring.cpp
@@ -7397,6 +7397,8 @@ float QString::toFloat(bool *ok) const
The formatting always uses QLocale::C, i.e., English/UnitedStates.
To get a localized string representation of a number, use
QLocale::toString() with the appropriate locale.
+
+ \sa number()
*/
/*! \fn QString &QString::setNum(uint n, int base)
@@ -7454,6 +7456,8 @@ QString &QString::setNum(qulonglong n, int base)
The formatting always uses QLocale::C, i.e., English/UnitedStates.
To get a localized string representation of a number, use
QLocale::toString() with the appropriate locale.
+
+ \sa number()
*/
QString &QString::setNum(double n, char f, int prec)
@@ -7472,6 +7476,8 @@ QString &QString::setNum(double n, char f, int prec)
The formatting always uses QLocale::C, i.e., English/UnitedStates.
To get a localized string representation of a number, use
QLocale::toString() with the appropriate locale.
+
+ \sa number()
*/
diff --git a/src/corelib/text/qstring.h b/src/corelib/text/qstring.h
index 65d702ff1c..f08c7b0d00 100644
--- a/src/corelib/text/qstring.h
+++ b/src/corelib/text/qstring.h
@@ -1116,7 +1116,7 @@ int QStringView::toWCharArray(wchar_t *array) const
if (sizeof(wchar_t) == sizeof(QChar)) {
if (auto src = data())
memcpy(array, src, sizeof(QChar) * size());
- return size();
+ return int(size()); // ### q6sizetype
} else {
return QString::toUcs4_helper(reinterpret_cast<const ushort *>(data()), int(size()),
reinterpret_cast<uint *>(array));
diff --git a/src/corelib/text/qstringview.cpp b/src/corelib/text/qstringview.cpp
index c4ddb06ea4..08dade7e68 100644
--- a/src/corelib/text/qstringview.cpp
+++ b/src/corelib/text/qstringview.cpp
@@ -528,9 +528,9 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \fn QString QStringView::arg(Args &&...args) const
- \fn QString QLatin1String::arg(Args &&...args) const
- \fn QString QString::arg(Args &&...args) const
+ \fn template <typename...Args> QString QStringView::arg(Args &&...args) const
+ \fn template <typename...Args> QString QLatin1String::arg(Args &&...args) const
+ \fn template <typename...Args> QString QString::arg(Args &&...args) const
\since 5.14
Replaces occurrences of \c{%N} in this string with the corresponding
diff --git a/src/corelib/thread/qmutex.cpp b/src/corelib/thread/qmutex.cpp
index 0508932d68..9bfd50f2d9 100644
--- a/src/corelib/thread/qmutex.cpp
+++ b/src/corelib/thread/qmutex.cpp
@@ -212,7 +212,6 @@ QMutex::~QMutex()
}
/*! \fn void QMutex::lock()
- \fn QRecursiveMutex::lock()
Locks the mutex. If another thread has locked the mutex then this
call will block until that thread has unlocked it.
@@ -237,7 +236,6 @@ void QMutex::lock() QT_MUTEX_LOCK_NOEXCEPT
}
/*! \fn bool QMutex::tryLock(int timeout)
- \fn bool QRecursiveMutex::tryLock(int timeout)
Attempts to lock the mutex. This function returns \c true if the lock
was obtained; otherwise it returns \c false. If another thread has
@@ -272,7 +270,6 @@ bool QMutex::tryLock(int timeout) QT_MUTEX_LOCK_NOEXCEPT
}
/*! \fn bool QMutex::try_lock()
- \fn bool QRecursiveMutex::try_lock()
\since 5.8
Attempts to lock the mutex. This function returns \c true if the lock
@@ -286,7 +283,6 @@ bool QMutex::tryLock(int timeout) QT_MUTEX_LOCK_NOEXCEPT
*/
/*! \fn template <class Rep, class Period> bool QMutex::try_lock_for(std::chrono::duration<Rep, Period> duration)
- \fn template <class Rep, class Period> bool QRecursiveMutex::try_lock_for(std::chrono::duration<Rep, Period> duration)
\since 5.8
Attempts to lock the mutex. This function returns \c true if the lock
@@ -311,7 +307,6 @@ bool QMutex::tryLock(int timeout) QT_MUTEX_LOCK_NOEXCEPT
*/
/*! \fn template<class Clock, class Duration> bool QMutex::try_lock_until(std::chrono::time_point<Clock, Duration> timePoint)
- \fn template<class Clock, class Duration> bool QRecursiveMutex::try_lock_until(std::chrono::time_point<Clock, Duration> timePoint)
\since 5.8
Attempts to lock the mutex. This function returns \c true if the lock
@@ -336,7 +331,6 @@ bool QMutex::tryLock(int timeout) QT_MUTEX_LOCK_NOEXCEPT
*/
/*! \fn void QMutex::unlock()
- \fn void QRecursiveMutex::unlock()
Unlocks the mutex. Attempting to unlock a mutex in a different
thread to the one that locked it results in an error. Unlocking a
diff --git a/src/corelib/time/qdatetime.cpp b/src/corelib/time/qdatetime.cpp
index 773280ad68..86c08058fc 100644
--- a/src/corelib/time/qdatetime.cpp
+++ b/src/corelib/time/qdatetime.cpp
@@ -1100,9 +1100,10 @@ QString QDate::longDayName(int weekday, MonthNameType type)
#if QT_CONFIG(datestring) // depends on, so implies, textdate
-static QString toStringTextDate(QDate date, QCalendar cal)
+static QString toStringTextDate(QDate date)
{
if (date.isValid()) {
+ QCalendar cal; // Always Gregorian
const auto parts = cal.partsFromDate(date);
if (parts.isValid()) {
const QLatin1Char sp(' ');
@@ -1123,14 +1124,10 @@ static QString toStringIsoDate(QDate date)
}
/*!
- \fn QString QDate::toString(Qt::DateFormat format) const
- \fn QString QDate::toString(Qt::DateFormat format, QCalendar cal) const
-
\overload
Returns the date as a string. The \a format parameter determines the format
- of the string. If \a cal is supplied, it determines the calendar used to
- represent the date; it defaults to Gregorian.
+ of the string.
If the \a format is Qt::TextDate, the string is formatted in the default
way. The day and month names will be localized names using the system
@@ -1168,16 +1165,44 @@ static QString toStringIsoDate(QDate date)
*/
QString QDate::toString(Qt::DateFormat format) const
{
- return toString(format, QCalendar());
+ if (!isValid())
+ return QString();
+
+ switch (format) {
+#if QT_DEPRECATED_SINCE(5, 15)
+QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
+ case Qt::SystemLocaleDate:
+ case Qt::SystemLocaleShortDate:
+ return QLocale::system().toString(*this, QLocale::ShortFormat);
+ case Qt::SystemLocaleLongDate:
+ return QLocale::system().toString(*this, QLocale::LongFormat);
+ case Qt::LocaleDate:
+ case Qt::DefaultLocaleShortDate:
+ return QLocale().toString(*this, QLocale::ShortFormat);
+ case Qt::DefaultLocaleLongDate:
+ return QLocale().toString(*this, QLocale::LongFormat);
+QT_WARNING_POP
+#endif // 5.15
+ case Qt::RFC2822Date:
+ return QLocale::c().toString(*this, QStringView(u"dd MMM yyyy"));
+ default:
+ case Qt::TextDate:
+ return toStringTextDate(*this);
+ case Qt::ISODate:
+ case Qt::ISODateWithMs:
+ // No calendar dependence
+ return toStringIsoDate(*this);
+ }
}
+#if QT_DEPRECATED_SINCE(5, 15)
QString QDate::toString(Qt::DateFormat format, QCalendar cal) const
{
if (!isValid())
return QString();
switch (format) {
-#if QT_DEPRECATED_SINCE(5, 15)
+QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
case Qt::SystemLocaleDate:
case Qt::SystemLocaleShortDate:
return QLocale::system().toString(*this, QLocale::ShortFormat, cal);
@@ -1188,18 +1213,19 @@ QString QDate::toString(Qt::DateFormat format, QCalendar cal) const
return QLocale().toString(*this, QLocale::ShortFormat, cal);
case Qt::DefaultLocaleLongDate:
return QLocale().toString(*this, QLocale::LongFormat, cal);
-#endif // 5.15
+QT_WARNING_POP
case Qt::RFC2822Date:
return QLocale::c().toString(*this, QStringView(u"dd MMM yyyy"), cal);
default:
case Qt::TextDate:
- return toStringTextDate(*this, cal);
+ return toStringTextDate(*this);
case Qt::ISODate:
case Qt::ISODateWithMs:
// No calendar dependence
return toStringIsoDate(*this);
}
}
+#endif // 5.15
/*!
\fn QString QDate::toString(const QString &format) const
@@ -1208,7 +1234,7 @@ QString QDate::toString(Qt::DateFormat format, QCalendar cal) const
\fn QString QDate::toString(QStringView format, QCalendar cal) const
Returns the date as a string. The \a format parameter determines the format
- of the result string. If \cal is supplied, it determines the calendar used
+ of the result string. If \a cal is supplied, it determines the calendar used
to represent the date; it defaults to Gregorian.
These expressions may be used:
@@ -1643,6 +1669,7 @@ QDate QDate::fromString(const QString &string, Qt::DateFormat format)
switch (format) {
#if QT_DEPRECATED_SINCE(5, 15)
+QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
case Qt::SystemLocaleDate:
case Qt::SystemLocaleShortDate:
return QLocale::system().toDate(string, QLocale::ShortFormat);
@@ -1653,6 +1680,7 @@ QDate QDate::fromString(const QString &string, Qt::DateFormat format)
return QLocale().toDate(string, QLocale::ShortFormat);
case Qt::DefaultLocaleLongDate:
return QLocale().toDate(string, QLocale::LongFormat);
+QT_WARNING_POP
#endif // 5.15
case Qt::RFC2822Date:
return rfcDateImpl(string).date;
@@ -2033,6 +2061,7 @@ QString QTime::toString(Qt::DateFormat format) const
switch (format) {
#if QT_DEPRECATED_SINCE(5, 15)
+QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
case Qt::SystemLocaleDate:
case Qt::SystemLocaleShortDate:
return QLocale::system().toString(*this, QLocale::ShortFormat);
@@ -2043,6 +2072,7 @@ QString QTime::toString(Qt::DateFormat format) const
return QLocale().toString(*this, QLocale::ShortFormat);
case Qt::DefaultLocaleLongDate:
return QLocale().toString(*this, QLocale::LongFormat);
+QT_WARNING_POP
#endif // 5.15
case Qt::ISODateWithMs:
return QString::asprintf("%02d:%02d:%02d.%03d", hour(), minute(), second(), msec());
@@ -2434,6 +2464,7 @@ QTime QTime::fromString(const QString &string, Qt::DateFormat format)
switch (format) {
#if QT_DEPRECATED_SINCE(5, 15)
+QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
case Qt::SystemLocaleDate:
case Qt::SystemLocaleShortDate:
return QLocale::system().toTime(string, QLocale::ShortFormat);
@@ -2444,6 +2475,7 @@ QTime QTime::fromString(const QString &string, Qt::DateFormat format)
return QLocale().toTime(string, QLocale::ShortFormat);
case Qt::DefaultLocaleLongDate:
return QLocale().toTime(string, QLocale::LongFormat);
+QT_WARNING_POP
#endif // 5.15
case Qt::RFC2822Date:
return rfcDateImpl(string).time;
@@ -4279,14 +4311,9 @@ void QDateTime::setTime_t(uint secsSince1Jan1970UTC)
#if QT_CONFIG(datestring) // depends on, so implies, textdate
/*!
- \fn QString QDateTime::toString(Qt::DateFormat format) const
- \fn QString QDateTime::toString(Qt::DateFormat format, QCalendar cal) const
-
\overload
- Returns the datetime as a string in the \a format given. If \cal is
- supplied, it determines the calendar used to represent the date; it defaults
- to Gregorian.
+ Returns the datetime as a string in the \a format given.
If the \a format is Qt::TextDate, the string is formatted in the default
way. The day and month names will be localized names using the system
@@ -4329,37 +4356,34 @@ void QDateTime::setTime_t(uint secsSince1Jan1970UTC)
QString QDateTime::toString(Qt::DateFormat format) const
{
- return toString(format, QCalendar());
-}
-
-QString QDateTime::toString(Qt::DateFormat format, QCalendar cal) const
-{
QString buf;
if (!isValid())
return buf;
switch (format) {
#if QT_DEPRECATED_SINCE(5, 15)
+QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
case Qt::SystemLocaleDate:
case Qt::SystemLocaleShortDate:
- return QLocale::system().toString(*this, QLocale::ShortFormat, cal);
+ return QLocale::system().toString(*this, QLocale::ShortFormat);
case Qt::SystemLocaleLongDate:
- return QLocale::system().toString(*this, QLocale::LongFormat, cal);
+ return QLocale::system().toString(*this, QLocale::LongFormat);
case Qt::LocaleDate:
case Qt::DefaultLocaleShortDate:
- return QLocale().toString(*this, QLocale::ShortFormat, cal);
+ return QLocale().toString(*this, QLocale::ShortFormat);
case Qt::DefaultLocaleLongDate:
- return QLocale().toString(*this, QLocale::LongFormat, cal);
+ return QLocale().toString(*this, QLocale::LongFormat);
+QT_WARNING_POP
#endif // 5.15
case Qt::RFC2822Date: {
- buf = QLocale::c().toString(*this, u"dd MMM yyyy hh:mm:ss ", cal);
+ buf = QLocale::c().toString(*this, u"dd MMM yyyy hh:mm:ss ");
buf += toOffsetString(Qt::TextDate, offsetFromUtc());
return buf;
}
default:
case Qt::TextDate: {
const QPair<QDate, QTime> p = getDateTime(d);
- buf = toStringTextDate(p.first, cal);
+ buf = toStringTextDate(p.first);
// Insert time between date's day and year:
buf.insert(buf.lastIndexOf(QLatin1Char(' ')),
QLatin1Char(' ') + p.second.toString(Qt::TextDate));
@@ -4381,7 +4405,6 @@ QString QDateTime::toString(Qt::DateFormat format, QCalendar cal) const
}
case Qt::ISODate:
case Qt::ISODateWithMs: {
- // No calendar dependence
const QPair<QDate, QTime> p = getDateTime(d);
buf = toStringIsoDate(p.first);
if (buf.isEmpty())
@@ -4412,7 +4435,7 @@ QString QDateTime::toString(Qt::DateFormat format, QCalendar cal) const
\fn QString QDateTime::toString(QStringView format, QCalendar cal) const
Returns the datetime as a string. The \a format parameter determines the
- format of the result string. If \cal is supplied, it determines the calendar
+ format of the result string. If \a cal is supplied, it determines the calendar
used to represent the date; it defaults to Gregorian. See QTime::toString()
and QDate::toString() for the supported specifiers for time and date,
respectively.
@@ -5228,6 +5251,7 @@ QDateTime QDateTime::fromString(const QString &string, Qt::DateFormat format)
switch (format) {
#if QT_DEPRECATED_SINCE(5, 15)
+QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
case Qt::SystemLocaleDate:
case Qt::SystemLocaleShortDate:
return QLocale::system().toDateTime(string, QLocale::ShortFormat);
@@ -5238,6 +5262,7 @@ QDateTime QDateTime::fromString(const QString &string, Qt::DateFormat format)
return QLocale().toDateTime(string, QLocale::ShortFormat);
case Qt::DefaultLocaleLongDate:
return QLocale().toDateTime(string, QLocale::LongFormat);
+QT_WARNING_POP
#endif // 5.15
case Qt::RFC2822Date: {
const ParsedRfcDateTime rfc = rfcDateImpl(string);
diff --git a/src/corelib/time/qdatetime.h b/src/corelib/time/qdatetime.h
index c1653b5585..645923ada8 100644
--- a/src/corelib/time/qdatetime.h
+++ b/src/corelib/time/qdatetime.h
@@ -111,7 +111,11 @@ public:
#endif // textdate && deprecated
#if QT_CONFIG(datestring)
QString toString(Qt::DateFormat format = Qt::TextDate) const;
+#if QT_DEPRECATED_SINCE(5, 15)
+ // Only the deprecated locale-dependent formats use the calendar.
+ QT_DEPRECATED_X("Use QLocale or omit the calendar")
QString toString(Qt::DateFormat format, QCalendar cal) const;
+#endif
#if QT_STRINGVIEW_LEVEL < 2
QString toString(const QString &format) const;
@@ -334,7 +338,6 @@ public:
#if QT_CONFIG(datestring)
QString toString(Qt::DateFormat format = Qt::TextDate) const;
- QString toString(Qt::DateFormat format, QCalendar cal) const;
#if QT_STRINGVIEW_LEVEL < 2
QString toString(const QString &format) const;
QString toString(const QString &format, QCalendar cal) const;
diff --git a/src/corelib/tools/qmap.cpp b/src/corelib/tools/qmap.cpp
index 9b9c67e42b..6d2b8f7a3e 100644
--- a/src/corelib/tools/qmap.cpp
+++ b/src/corelib/tools/qmap.cpp
@@ -1999,7 +1999,7 @@ void QMapDataBase::freeData(QMapDataBase *d)
\sa replace()
*/
-/*! \fn template <class Key, class T> typename QMultiMap<Key, T>::iterator QMultiMap<Key, T>::insert(typename QMultiMap<Key, T>::const_iterator pos, const Key &key, const T &value)
+/*! \fn [qmultimap-insert-pos] template <class Key, class T> typename QMultiMap<Key, T>::iterator QMultiMap<Key, T>::insert(typename QMultiMap<Key, T>::const_iterator pos, const Key &key, const T &value)
\since 5.1
Inserts a new item with the key \a key and value \a value and with hint \a pos
@@ -2128,7 +2128,8 @@ void QMapDataBase::freeData(QMapDataBase *d)
once in the returned list.
*/
-/*! \fn template <class Key, class T> QMultiMap<Key, T> &QMultiMap<Key, T>::unite(const QMultiMap<Key, T> &other)
+/*!
+ \fn [qmultimap-unite] template <class Key, class T> QMultiMap<Key, T> &QMultiMap<Key, T>::unite(const QMultiMap<Key, T> &other)
Inserts all the items in the \a other map into this map. If a
key is common to both maps, the resulting map will contain the
diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h
index a70b355c67..a971919e54 100644
--- a/src/corelib/tools/qmap.h
+++ b/src/corelib/tools/qmap.h
@@ -1086,14 +1086,14 @@ public:
QList<Key> uniqueKeys() const;
QList<T> values(const Key &key) const;
- using typename QMap<Key, T>::iterator;
- using typename QMap<Key, T>::const_iterator;
-
inline typename QMap<Key, T>::iterator replace(const Key &key, const T &value)
{ return QMap<Key, T>::insert(key, value); }
- iterator insert(const Key &key, const T &value);
- iterator insert(const_iterator pos, const Key &key, const T &value);
+ typename QMap<Key, T>::iterator insert(const Key &key, const T &value);
+ //! [qmultimap-insert-pos]
+ typename QMap<Key, T>::iterator insert(typename QMap<Key, T>::const_iterator pos,
+ const Key &key, const T &value);
+ //! [qmultimap-unite]
QMultiMap &unite(const QMultiMap &other);
inline QMultiMap &operator+=(const QMultiMap &other)
{ return unite(other); }
@@ -1151,7 +1151,7 @@ Q_OUTOFLINE_TEMPLATE QList<Key> QMultiMap<Key, T>::uniqueKeys() const
{
QList<Key> res;
res.reserve(size()); // May be too much, but assume short lifetime
- const_iterator i = this->begin();
+ typename QMap<Key, T>::const_iterator i = this->begin();
if (i != this->end()) {
for (;;) {
const Key &aKey = i.key();
@@ -1172,7 +1172,7 @@ Q_OUTOFLINE_TEMPLATE QList<T> QMultiMap<Key, T>::values(const Key &akey) const
QList<T> res;
Node *n = this->d->findNode(akey);
if (n) {
- const_iterator it(n);
+ typename QMap<Key, T>::const_iterator it(n);
do {
res.append(*it);
++it;
@@ -1182,8 +1182,8 @@ Q_OUTOFLINE_TEMPLATE QList<T> QMultiMap<Key, T>::values(const Key &akey) const
}
template <class Key, class T>
-Q_INLINE_TEMPLATE typename QMultiMap<Key, T>::iterator QMultiMap<Key, T>::insert(const Key &akey,
- const T &avalue)
+Q_INLINE_TEMPLATE typename QMap<Key, T>::iterator QMultiMap<Key, T>::insert(const Key &akey,
+ const T &avalue)
{
detach();
Node* y = this->d->end();
@@ -1195,11 +1195,13 @@ Q_INLINE_TEMPLATE typename QMultiMap<Key, T>::iterator QMultiMap<Key, T>::insert
x = left ? x->leftNode() : x->rightNode();
}
Node *z = this->d->createNode(akey, avalue, y, left);
- return iterator(z);
+ return typename QMap<Key, T>::iterator(z);
}
+#ifndef Q_CLANG_QDOC
template <class Key, class T>
-typename QMultiMap<Key, T>::iterator QMultiMap<Key, T>::insert(const_iterator pos, const Key &akey, const T &avalue)
+typename QMap<Key, T>::iterator QMultiMap<Key, T>::insert(typename QMap<Key, T>::const_iterator pos,
+ const Key &akey, const T &avalue)
{
if (this->d->ref.isShared())
return insert(akey, avalue);
@@ -1216,7 +1218,7 @@ typename QMultiMap<Key, T>::iterator QMultiMap<Key, T>::insert(const_iterator po
if (!qMapLessThanKey(n->key, akey))
return insert(akey, avalue); // ignore hint
Node *z = this->d->createNode(akey, avalue, n, false); // insert right most
- return iterator(z);
+ return typename QMap<Key, T>::iterator(z);
}
return insert(akey, avalue);
} else {
@@ -1229,7 +1231,7 @@ typename QMultiMap<Key, T>::iterator QMultiMap<Key, T>::insert(const_iterator po
if (pos == this->constBegin()) {
// There is no previous value (insert left most)
Node *z = this->d->createNode(akey, avalue, this->begin().i, true);
- return iterator(z);
+ return typename QMap<Key, T>::iterator(z);
} else {
Node *prev = const_cast<Node*>(pos.i->previousNode());
if (!qMapLessThanKey(prev->key, akey))
@@ -1238,11 +1240,11 @@ typename QMultiMap<Key, T>::iterator QMultiMap<Key, T>::insert(const_iterator po
// Hint is ok - do insert
if (prev->right == nullptr) {
Node *z = this->d->createNode(akey, avalue, prev, false);
- return iterator(z);
+ return typename QMap<Key, T>::iterator(z);
}
if (next->left == nullptr) {
Node *z = this->d->createNode(akey, avalue, next, true);
- return iterator(z);
+ return typename QMap<Key, T>::iterator(z);
}
Q_ASSERT(false); // We should have prev->right == nullptr or next->left == nullptr.
return insert(akey, avalue);
@@ -1254,14 +1256,15 @@ template <class Key, class T>
Q_INLINE_TEMPLATE QMultiMap<Key, T> &QMultiMap<Key, T>::unite(const QMultiMap<Key, T> &other)
{
QMultiMap<Key, T> copy(other);
- const_iterator it = copy.constEnd();
- const const_iterator b = copy.constBegin();
+ typename QMap<Key, T>::const_iterator it = copy.constEnd();
+ const typename QMap<Key, T>::const_iterator b = copy.constBegin();
while (it != b) {
--it;
insert(it.key(), it.value());
}
return *this;
}
+#endif // Q_CLANG_QDOC
template <class Key, class T>
Q_INLINE_TEMPLATE bool QMultiMap<Key, T>::contains(const Key &key, const T &value) const
@@ -1293,8 +1296,8 @@ Q_INLINE_TEMPLATE int QMultiMap<Key, T>::count(const Key &akey) const
QMultiMap::Node *lastNode;
this->d->nodeRange(akey, &firstNode, &lastNode);
- const_iterator ci_first(firstNode);
- const const_iterator ci_last(lastNode);
+ typename QMap<Key, T>::const_iterator ci_first(firstNode);
+ const typename QMap<Key, T>::const_iterator ci_last(lastNode);
int cnt = 0;
while (ci_first != ci_last) {
++cnt;
diff --git a/src/corelib/tools/qvarlengtharray.qdoc b/src/corelib/tools/qvarlengtharray.qdoc
index a0e9abe0ae..d530e4358e 100644
--- a/src/corelib/tools/qvarlengtharray.qdoc
+++ b/src/corelib/tools/qvarlengtharray.qdoc
@@ -903,7 +903,7 @@
*/
/*!
- template <typename T, int Prealloc> uint qHash(const QVarLengthArray<T, Prealloc> &key, uint seed = 0)
+ \fn template <typename T, int Prealloc> uint qHash(const QVarLengthArray<T, Prealloc> &key, uint seed = 0)
\relates QVarLengthArray
\since 5.14
diff --git a/src/gui/.prev_CMakeLists.txt b/src/gui/.prev_CMakeLists.txt
index 953dc8b2da..36e53a0edc 100644
--- a/src/gui/.prev_CMakeLists.txt
+++ b/src/gui/.prev_CMakeLists.txt
@@ -494,7 +494,7 @@ qt_extend_target(Gui CONDITION QT_FEATURE_textmarkdownreader
)
qt_extend_target(Gui CONDITION QT_FEATURE_system_textmarkdownreader AND QT_FEATURE_textmarkdownreader
- PUBLIC_LIBRARIES
+ LIBRARIES
libmd4c
)
diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt
index 14859069a5..eb3b07fdae 100644
--- a/src/gui/CMakeLists.txt
+++ b/src/gui/CMakeLists.txt
@@ -599,7 +599,7 @@ qt_extend_target(Gui CONDITION QT_FEATURE_textmarkdownreader
)
qt_extend_target(Gui CONDITION QT_FEATURE_system_textmarkdownreader AND QT_FEATURE_textmarkdownreader
- PUBLIC_LIBRARIES
+ LIBRARIES
libmd4c
)
diff --git a/src/gui/image/qimage.h b/src/gui/image/qimage.h
index a9c0fbbe3e..5a1524b419 100644
--- a/src/gui/image/qimage.h
+++ b/src/gui/image/qimage.h
@@ -231,7 +231,8 @@ public:
bool hasAlphaChannel() const;
void setAlphaChannel(const QImage &alphaChannel);
#if QT_DEPRECATED_SINCE(5, 15)
- QT_DEPRECATED QImage alphaChannel() const;
+ QT_DEPRECATED_X("Use convertToFormat(QImage::Format_Alpha8)")
+ QImage alphaChannel() const;
#endif
QImage createAlphaMask(Qt::ImageConversionFlags flags = Qt::AutoColor) const;
#ifndef QT_NO_IMAGE_HEURISTIC_MASK
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp
index c2dac71e0d..5ad37ae640 100644
--- a/src/gui/kernel/qevent.cpp
+++ b/src/gui/kernel/qevent.cpp
@@ -2368,6 +2368,7 @@ QTabletEvent::QTabletEvent(Type type, const QPointF &pos, const QPointF &globalP
{
}
+#if QT_DEPRECATED_SINCE(5, 15)
/*!
Construct a tablet event of the given \a type.
@@ -2411,6 +2412,7 @@ QTabletEvent::QTabletEvent(Type type, const QPointF &pos, const QPointF &globalP
tangentialPressure, rotation, z, keyState, uniqueID, Qt::NoButton, Qt::NoButton)
{
}
+#endif
/*!
\internal
@@ -2451,6 +2453,12 @@ Qt::MouseButtons QTabletEvent::buttons() const
/*!
\fn TabletDevices QTabletEvent::device() const
+ \deprecated Use deviceType().
+*/
+
+/*!
+ \fn TabletDevices QTabletEvent::deviceType() const
+
Returns the type of device that generated the event.
\sa TabletDevice
@@ -2615,12 +2623,16 @@ Qt::MouseButtons QTabletEvent::buttons() const
\fn qreal &QTabletEvent::hiResGlobalX() const
The high precision x position of the tablet device.
+
+ \obsolete use globalPosF()
*/
/*!
\fn qreal &QTabletEvent::hiResGlobalY() const
The high precision y position of the tablet device.
+
+ \obsolete use globalPosF()
*/
/*!
diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h
index 6f3215652b..87ec8e7bee 100644
--- a/src/gui/kernel/qevent.h
+++ b/src/gui/kernel/qevent.h
@@ -280,10 +280,15 @@ public:
Q_ENUM(TabletDevice)
enum PointerType { UnknownPointer, Pen, Cursor, Eraser };
Q_ENUM(PointerType)
+
+#if QT_DEPRECATED_SINCE(5, 15)
+ // Actually deprecated since 5.4, in docs
+ QT_DEPRECATED_VERSION_X_5_15("Use the other QTabletEvent constructor")
QTabletEvent(Type t, const QPointF &pos, const QPointF &globalPos,
int device, int pointerType, qreal pressure, int xTilt, int yTilt,
qreal tangentialPressure, qreal rotation, int z,
Qt::KeyboardModifiers keyState, qint64 uniqueID); // ### remove in Qt 6
+#endif
QTabletEvent(Type t, const QPointF &pos, const QPointF &globalPos,
int device, int pointerType, qreal pressure, int xTilt, int yTilt,
qreal tangentialPressure, qreal rotation, int z,
@@ -304,9 +309,15 @@ public:
inline int y() const { return qRound(mPos.y()); }
inline int globalX() const { return qRound(mGPos.x()); }
inline int globalY() const { return qRound(mGPos.y()); }
+#if QT_DEPRECATED_SINCE(5, 15)
+ QT_DEPRECATED_VERSION_X_5_15("use globalPosF().x()")
inline qreal hiResGlobalX() const { return mGPos.x(); }
+ QT_DEPRECATED_VERSION_X_5_15("use globalPosF().y()")
inline qreal hiResGlobalY() const { return mGPos.y(); }
+ QT_DEPRECATED_VERSION_X_5_15("Use deviceType()")
inline TabletDevice device() const { return TabletDevice(mDev); }
+#endif
+ inline TabletDevice deviceType() const { return TabletDevice(mDev); }
inline PointerType pointerType() const { return PointerType(mPointerType); }
inline qint64 uniqueId() const { return mUnique; }
inline qreal pressure() const { return mPress; }
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index 1f8d8d21e9..5a9274e4f3 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -610,7 +610,7 @@ static QWindowGeometrySpecification windowGeometrySpecification = Q_WINDOW_GEOME
\li \c {dialogs=[xp|none]}, \c xp uses XP-style native dialogs and
\c none disables them.
- \li \c {dpiawareness=[0|1|2} Sets the DPI awareness of the process
+ \li \c {dpiawareness=[0|1|2]} Sets the DPI awareness of the process
(see \l{High DPI Displays}, since Qt 5.4).
\li \c {fontengine=freetype}, uses the FreeType font engine.
\li \c {fontengine=directwrite}, uses the experimental DirectWrite
@@ -1738,6 +1738,8 @@ QGuiApplicationPrivate::~QGuiApplicationPrivate()
window_list.clear();
screen_list.clear();
+
+ self = nullptr;
}
#if 0
@@ -1891,6 +1893,10 @@ bool QGuiApplication::event(QEvent *e)
{
if(e->type() == QEvent::LanguageChange) {
setLayoutDirection(qt_detectRTLLanguage()?Qt::RightToLeft:Qt::LeftToRight);
+ for (auto *topLevelWindow : QGuiApplication::topLevelWindows()) {
+ if (topLevelWindow->flags() != Qt::Desktop)
+ postEvent(topLevelWindow, new QEvent(QEvent::LanguageChange));
+ }
} else if (e->type() == QEvent::Quit) {
// Close open windows. This is done in order to deliver de-expose
// events while the event loop is still running.
@@ -3412,8 +3418,11 @@ void QGuiApplicationPrivate::applyWindowGeometrySpecificationTo(QWindow *window)
*/
QFont QGuiApplication::font()
{
- Q_ASSERT_X(QGuiApplicationPrivate::self, "QGuiApplication::font()", "no QGuiApplication instance");
const auto locker = qt_scoped_lock(applicationFontMutex);
+ if (!QGuiApplicationPrivate::self && !QGuiApplicationPrivate::app_font) {
+ qWarning("QGuiApplication::font(): no QGuiApplication instance and no application font set.");
+ return QFont(); // in effect: QFont((QFontPrivate*)nullptr), so no recursion
+ }
initFontUnlocked();
return *QGuiApplicationPrivate::app_font;
}
diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp
index e544fce70e..eac2a50c8c 100644
--- a/src/gui/painting/qcolor.cpp
+++ b/src/gui/painting/qcolor.cpp
@@ -3224,6 +3224,7 @@ const uint qt_inv_premul_factor[256] = {
/*!
\namespace QColorConstants
\inmodule QtGui
+ \since 5.14
\brief The QColorConstants namespace contains QColor predefined constants.
diff --git a/src/gui/painting/qicc.cpp b/src/gui/painting/qicc.cpp
index 18f212f8e9..2b5cd58fb1 100644
--- a/src/gui/painting/qicc.cpp
+++ b/src/gui/painting/qicc.cpp
@@ -87,6 +87,11 @@ constexpr quint32 IccTag(uchar a, uchar b, uchar c, uchar d)
return (a << 24) | (b << 16) | (c << 8) | d;
}
+enum class ColorSpaceType : quint32 {
+ Rgb = IccTag('R', 'G', 'B', ' '),
+ Gray = IccTag('G', 'R', 'A', 'Y'),
+};
+
enum class ProfileClass : quint32 {
Input = IccTag('s', 'c', 'r', 'n'),
Display = IccTag('m', 'n', 't', 'r'),
@@ -105,6 +110,7 @@ enum class Tag : quint32 {
rTRC = IccTag('r', 'T', 'R', 'C'),
gTRC = IccTag('g', 'T', 'R', 'C'),
bTRC = IccTag('b', 'T', 'R', 'C'),
+ kTRC = IccTag('k', 'T', 'R', 'C'),
A2B0 = IccTag('A', '2', 'B', '0'),
A2B1 = IccTag('A', '2', 'B', '1'),
B2A0 = IccTag('B', '2', 'A', '0'),
@@ -219,8 +225,10 @@ static bool isValidIccProfile(const ICCProfileHeader &header)
}
// Don't overflow 32bit integers:
- if (header.tagCount >= INT32_MAX / sizeof(TagTableEntry))
+ if (header.tagCount >= INT32_MAX / sizeof(TagTableEntry)) {
+ qCWarning(lcIcc, "Failed tag count sanity");
return false;
+ }
if (header.profileSize - sizeof(ICCProfileHeader) < header.tagCount * sizeof(TagTableEntry)) {
qCWarning(lcIcc, "Failed basic size sanity");
return false;
@@ -231,7 +239,8 @@ static bool isValidIccProfile(const ICCProfileHeader &header)
qCWarning(lcIcc, "Unsupported ICC profile class %x", quint32(header.profileClass));
return false;
}
- if (header.inputColorSpace != 0x52474220 /* 'RGB '*/) {
+ if (header.inputColorSpace != uint(ColorSpaceType::Rgb)
+ && header.inputColorSpace != uint(ColorSpaceType::Gray)) {
qCWarning(lcIcc, "Unsupported ICC input color space %x", quint32(header.inputColorSpace));
return false;
}
@@ -610,10 +619,8 @@ bool fromIccProfile(const QByteArray &data, QColorSpace *colorSpace)
return false;
}
const ICCProfileHeader *header = (const ICCProfileHeader *)data.constData();
- if (!isValidIccProfile(*header)) {
- qCWarning(lcIcc) << "fromIccProfile: failed general sanity check";
- return false;
- }
+ if (!isValidIccProfile(*header))
+ return false; // if failed we already printing a warning
if (qsizetype(header->profileSize) > data.size()) {
qCWarning(lcIcc) << "fromIccProfile: failed size sanity 2";
return false;
@@ -658,39 +665,74 @@ bool fromIccProfile(const QByteArray &data, QColorSpace *colorSpace)
}
// Check the profile is three-component matrix based (what we currently support):
- if (!tagIndex.contains(Tag::rXYZ) || !tagIndex.contains(Tag::gXYZ) || !tagIndex.contains(Tag::bXYZ) ||
- !tagIndex.contains(Tag::rTRC) || !tagIndex.contains(Tag::gTRC) || !tagIndex.contains(Tag::bTRC) ||
- !tagIndex.contains(Tag::wtpt)) {
- qCWarning(lcIcc) << "fromIccProfile: Unsupported ICC profile - not three component matrix based";
- return false;
+ if (header->inputColorSpace == uint(ColorSpaceType::Rgb)) {
+ if (!tagIndex.contains(Tag::rXYZ) || !tagIndex.contains(Tag::gXYZ) || !tagIndex.contains(Tag::bXYZ) ||
+ !tagIndex.contains(Tag::rTRC) || !tagIndex.contains(Tag::gTRC) || !tagIndex.contains(Tag::bTRC) ||
+ !tagIndex.contains(Tag::wtpt)) {
+ qCWarning(lcIcc) << "fromIccProfile: Unsupported ICC profile - not three component matrix based";
+ return false;
+ }
+ } else {
+ Q_ASSERT(header->inputColorSpace == uint(ColorSpaceType::Gray));
+ if (!tagIndex.contains(Tag::kTRC) || !tagIndex.contains(Tag::wtpt)) {
+ qCWarning(lcIcc) << "fromIccProfile: Invalid ICC profile - not valid gray scale based";
+ return false;
+ }
}
QColorSpacePrivate *colorspaceDPtr = QColorSpacePrivate::getWritable(*colorSpace);
- // Parse XYZ tags
- if (!parseXyzData(data, tagIndex[Tag::rXYZ], colorspaceDPtr->toXyz.r))
- return false;
- if (!parseXyzData(data, tagIndex[Tag::gXYZ], colorspaceDPtr->toXyz.g))
- return false;
- if (!parseXyzData(data, tagIndex[Tag::bXYZ], colorspaceDPtr->toXyz.b))
- return false;
- if (!parseXyzData(data, tagIndex[Tag::wtpt], colorspaceDPtr->whitePoint))
- return false;
+ if (header->inputColorSpace == uint(ColorSpaceType::Rgb)) {
+ // Parse XYZ tags
+ if (!parseXyzData(data, tagIndex[Tag::rXYZ], colorspaceDPtr->toXyz.r))
+ return false;
+ if (!parseXyzData(data, tagIndex[Tag::gXYZ], colorspaceDPtr->toXyz.g))
+ return false;
+ if (!parseXyzData(data, tagIndex[Tag::bXYZ], colorspaceDPtr->toXyz.b))
+ return false;
+ if (!parseXyzData(data, tagIndex[Tag::wtpt], colorspaceDPtr->whitePoint))
+ return false;
- colorspaceDPtr->primaries = QColorSpace::Primaries::Custom;
- if (colorspaceDPtr->toXyz == QColorMatrix::toXyzFromSRgb()) {
- qCDebug(lcIcc) << "fromIccProfile: sRGB primaries detected";
- colorspaceDPtr->primaries = QColorSpace::Primaries::SRgb;
- } else if (colorspaceDPtr->toXyz == QColorMatrix::toXyzFromAdobeRgb()) {
- qCDebug(lcIcc) << "fromIccProfile: Adobe RGB primaries detected";
- colorspaceDPtr->primaries = QColorSpace::Primaries::AdobeRgb;
- } else if (colorspaceDPtr->toXyz == QColorMatrix::toXyzFromDciP3D65()) {
- qCDebug(lcIcc) << "fromIccProfile: DCI-P3 D65 primaries detected";
- colorspaceDPtr->primaries = QColorSpace::Primaries::DciP3D65;
- }
- if (colorspaceDPtr->toXyz == QColorMatrix::toXyzFromProPhotoRgb()) {
- qCDebug(lcIcc) << "fromIccProfile: ProPhoto RGB primaries detected";
- colorspaceDPtr->primaries = QColorSpace::Primaries::ProPhotoRgb;
+ colorspaceDPtr->primaries = QColorSpace::Primaries::Custom;
+ if (colorspaceDPtr->toXyz == QColorMatrix::toXyzFromSRgb()) {
+ qCDebug(lcIcc) << "fromIccProfile: sRGB primaries detected";
+ colorspaceDPtr->primaries = QColorSpace::Primaries::SRgb;
+ } else if (colorspaceDPtr->toXyz == QColorMatrix::toXyzFromAdobeRgb()) {
+ qCDebug(lcIcc) << "fromIccProfile: Adobe RGB primaries detected";
+ colorspaceDPtr->primaries = QColorSpace::Primaries::AdobeRgb;
+ } else if (colorspaceDPtr->toXyz == QColorMatrix::toXyzFromDciP3D65()) {
+ qCDebug(lcIcc) << "fromIccProfile: DCI-P3 D65 primaries detected";
+ colorspaceDPtr->primaries = QColorSpace::Primaries::DciP3D65;
+ }
+ if (colorspaceDPtr->toXyz == QColorMatrix::toXyzFromProPhotoRgb()) {
+ qCDebug(lcIcc) << "fromIccProfile: ProPhoto RGB primaries detected";
+ colorspaceDPtr->primaries = QColorSpace::Primaries::ProPhotoRgb;
+ }
+ } else {
+ // We will use sRGB primaries and fit to match the given white-point if
+ // it doesn't match sRGB's.
+ QColorVector whitePoint;
+ if (!parseXyzData(data, tagIndex[Tag::wtpt], whitePoint))
+ return false;
+ if (!qFuzzyCompare(whitePoint.y, 1.0f) || (1.0f + whitePoint.z - whitePoint.x) == 0.0f) {
+ qCWarning(lcIcc) << "fromIccProfile: Invalid ICC profile - gray white-point not normalized";
+ return false;
+ }
+ if (whitePoint == QColorVector::D65()) {
+ colorspaceDPtr->primaries = QColorSpace::Primaries::SRgb;
+ } else {
+ colorspaceDPtr->primaries = QColorSpace::Primaries::Custom;
+ // Calculate chromaticity from xyz (assuming y == 1.0f).
+ float y = 1.0f / (1.0f + whitePoint.z - whitePoint.x);
+ float x = whitePoint.x * y;
+ QColorSpacePrimaries primaries(QColorSpace::Primaries::SRgb);
+ primaries.whitePoint = QPointF(x,y);
+ if (!primaries.areValid()) {
+ qCWarning(lcIcc) << "fromIccProfile: Invalid ICC profile - invalid white-point";
+ return false;
+ }
+ colorspaceDPtr->toXyz = primaries.toXyzMatrix();
+ }
}
// Reset the matrix to our canonical values:
if (colorspaceDPtr->primaries != QColorSpace::Primaries::Custom)
@@ -700,7 +742,11 @@ bool fromIccProfile(const QByteArray &data, QColorSpace *colorSpace)
TagEntry rTrc;
TagEntry gTrc;
TagEntry bTrc;
- if (tagIndex.contains(Tag::aarg) && tagIndex.contains(Tag::aagg) && tagIndex.contains(Tag::aabg)) {
+ if (header->inputColorSpace == uint(ColorSpaceType::Gray)) {
+ rTrc = tagIndex[Tag::kTRC];
+ gTrc = tagIndex[Tag::kTRC];
+ bTrc = tagIndex[Tag::kTRC];
+ } else if (tagIndex.contains(Tag::aarg) && tagIndex.contains(Tag::aagg) && tagIndex.contains(Tag::aabg)) {
// Apple extension for parametric version of TRCs in ICCv2:
rTrc = tagIndex[Tag::aarg];
gTrc = tagIndex[Tag::aagg];
diff --git a/src/gui/rhi/qrhi.cpp b/src/gui/rhi/qrhi.cpp
index f0bf19bd91..7a0d53e1e4 100644
--- a/src/gui/rhi/qrhi.cpp
+++ b/src/gui/rhi/qrhi.cpp
@@ -577,6 +577,11 @@ Q_LOGGING_CATEGORY(QRHI_LOG_INFO, "qt.rhi.general")
specifying a non-zero level in QRhiReadbackDescription leads to returning
an all-zero image. In practice this feature will be unsupported with OpenGL
ES 2.0, while it will likely be supported everywhere else.
+
+ \value TexelFetch Indicates that texelFetch() is available in shaders. In
+ practice this will be reported as unsupported with OpenGL ES 2.0 and OpenGL
+ 2.x contexts, because GLSL 100 es and versions before 130 do not support
+ this function.
*/
/*!
@@ -622,18 +627,27 @@ Q_LOGGING_CATEGORY(QRHI_LOG_INFO, "qt.rhi.general")
is what some OpenGL ES implementations provide.
\value FramesInFlight The number of frames the backend may keep "in
- flight". The value has no relevance, and is unspecified, with backends like
- OpenGL and Direct3D 11. With backends like Vulkan or Metal, it is the
- responsibility of QRhi to block whenever starting a new frame and finding
- the CPU is already \c{N - 1} frames ahead of the GPU (because the command
- buffer submitted in frame no. \c{current} - \c{N} has not yet completed).
- The value N is what is returned from here, and is typically 2. This can be
- relevant to applications that integrate rendering done directly with the
- graphics API, as such rendering code may want to perform double (if the
- value is 2) buffering for resources, such as, buffers, similarly to the
- QRhi backends themselves. The current frame slot index (a value running 0,
- 1, .., N-1, then wrapping around) is retrievable from
- QRhi::currentFrameSlot().
+ flight": with backends like Vulkan or Metal, it is the responsibility of
+ QRhi to block whenever starting a new frame and finding the CPU is already
+ \c{N - 1} frames ahead of the GPU (because the command buffer submitted in
+ frame no. \c{current} - \c{N} has not yet completed). The value N is what
+ is returned from here, and is typically 2. This can be relevant to
+ applications that integrate rendering done directly with the graphics API,
+ as such rendering code may want to perform double (if the value is 2)
+ buffering for resources, such as, buffers, similarly to the QRhi backends
+ themselves. The current frame slot index (a value running 0, 1, .., N-1,
+ then wrapping around) is retrievable from QRhi::currentFrameSlot(). The
+ value is 1 for backends where the graphics API offers no such low level
+ control over the command submission process. Note that pipelining may still
+ happen even when this value is 1 (some backends, such as D3D11, are
+ designed to attempt to enable this, for instance, by using an update
+ strategy for uniform buffers that does not stall the pipeline), but that is
+ then not controlled by QRhi and so not reflected here in the API.
+
+ \value MaxAsyncReadbackFrames The number of \l{QRhi::endFrame()}{submitted}
+ frames (including the one that contains the readback) after which an
+ asynchronous texture or buffer readback is guaranteed to complete upon
+ \l{QRhi::beginFrame()}{starting a new frame}.
*/
/*!
@@ -1946,6 +1960,40 @@ quint64 QRhiResource::globalResourceId() const
*/
/*!
+ \class QRhiBuffer::NativeBuffer
+ \brief Contains information about the underlying native resources of a buffer.
+ */
+
+/*!
+ \variable QRhiBuffer::NativeBuffer::objects
+ \brief an array with pointers to the native object handles.
+
+ With OpenGL, the native handle is a GLuint value, so the elements in the \c
+ objects array are pointers to a GLuint. With Vulkan, the native handle is a
+ VkBuffer, so the elements of the array are pointers to a VkBuffer. With
+ Direct3D 11 and Metal the elements are pointers to a ID3D11Buffer or
+ MTLBuffer pointer, respectively.
+
+ \note Pay attention to the fact that the elements are always pointers to
+ the native buffer handle type, even if the native type itself is a pointer.
+ */
+
+/*!
+ \variable QRhiBuffer::NativeBuffer::slotCount
+ \brief Specifies the number of valid elements in the objects array.
+
+ The value can be 0, 1, 2, or 3 in practice. 0 indicates that the QRhiBuffer
+ is not backed by any native buffer objects. This can happen with
+ QRhiBuffers with the usage UniformBuffer when the underlying API does not
+ support (or the backend chooses not to use) native uniform buffers. 1 is
+ commonly used for Immutable and Static types (but some backends may
+ differ). 2 or 3 is typical when the type is Dynamic (but some backends may
+ differ).
+
+ \sa QRhi::currentFrameSlot(), QRhi::FramesInFlight
+ */
+
+/*!
\internal
*/
QRhiBuffer::QRhiBuffer(QRhiImplementation *rhi, Type type_, UsageFlags usage_, int size_)
@@ -1974,6 +2022,46 @@ QRhiResource::Type QRhiBuffer::resourceType() const
*/
/*!
+ \return the underlying native resources for this buffer. The returned value
+ will be empty if exposing the underlying native resources is not supported by
+ the backend.
+
+ A QRhiBuffer may be backed by multiple native buffer objects, depending on
+ the type() and the QRhi backend in use. When this is the case, all of them
+ are returned in the objects array in the returned struct, with slotCount
+ specifying the number of native buffer objects. While
+ \l{QRhi::beginFrame()}{recording a frame}, QRhi::currentFrameSlot() can be
+ used to determine which of the native buffers QRhi is using for operations
+ that read or write from this QRhiBuffer within the frame being recorded.
+
+ In some cases a QRhiBuffer will not be backed by a native buffer object at
+ all. In this case slotCount will be set to 0 and no valid native objects
+ are returned. This is not an error, and is perfectly valid when a given
+ backend does not use native buffers for QRhiBuffers with certain types or
+ usages.
+
+ \note Be aware that QRhi backends may employ various buffer update
+ strategies. Unlike textures, where uploading image data always means
+ recording a buffer-to-image (or similar) copy command on the command
+ buffer, buffers, in particular Dynamic and UniformBuffer ones, can operate
+ in many different ways. For example, a QRhiBuffer with usage type
+ UniformBuffer may not even be backed by a native buffer object at all if
+ uniform buffers are not used or supported by a given backend and graphics
+ API. There are also differences to how data is written to the buffer and
+ the type of backing memory used, and, if host visible memory is involved,
+ when memory writes become available and visible. Therefore, in general it
+ is recommended to limit native buffer object access to vertex and index
+ buffers with types Static or Immutable, because these operate in a
+ relatively uniform manner with all backends.
+
+ \sa QRhi::currentFrameSlot(), QRhi::FramesInFlight
+ */
+QRhiBuffer::NativeBuffer QRhiBuffer::nativeBuffer()
+{
+ return {};
+}
+
+/*!
\class QRhiRenderBuffer
\internal
\inmodule QtGui
@@ -4334,7 +4422,15 @@ void QRhiResourceUpdateBatch::uploadStaticBuffer(QRhiBuffer *buf, const void *da
is supported only when the QRhi::ReadBackNonUniformBuffer feature is
reported as supported.
- \a readBackTexture(), QRhi::isFeatureSupported()
+ \note The asynchronous readback is guaranteed to have completed when one of
+ the following conditions is met: \l{QRhi::finish()}{finish()} has been
+ called; or, at least \c N frames have been \l{QRhi::endFrame()}{submitted},
+ including the frame that issued the readback operation, and the
+ \l{QRhi::beginFrame()}{recording of a new frame} has been started, where \c
+ N is the \l{QRhi::resourceLimit()}{resource limit value} returned for
+ QRhi::MaxAsyncReadbackFrames.
+
+ \sa readBackTexture(), QRhi::isFeatureSupported(), QRhi::resourceLimit()
*/
void QRhiResourceUpdateBatch::readBackBuffer(QRhiBuffer *buf, int offset, int size, QRhiBufferReadbackResult *result)
{
@@ -4425,6 +4521,16 @@ void QRhiResourceUpdateBatch::copyTexture(QRhiTexture *dst, QRhiTexture *src, co
happens with a byte ordered format. A \l{QRhiTexture::RGBA8}{RGBA8} texture
maps therefore to byte ordered QImage formats, such as,
QImage::Format_RGBA8888.
+
+ \note The asynchronous readback is guaranteed to have completed when one of
+ the following conditions is met: \l{QRhi::finish()}{finish()} has been
+ called; or, at least \c N frames have been \l{QRhi::endFrame()}{submitted},
+ including the frame that issued the readback operation, and the
+ \l{QRhi::beginFrame()}{recording of a new frame} has been started, where \c
+ N is the \l{QRhi::resourceLimit()}{resource limit value} returned for
+ QRhi::MaxAsyncReadbackFrames.
+
+ \sa readBackBuffer(), QRhi::resourceLimit()
*/
void QRhiResourceUpdateBatch::readBackTexture(const QRhiReadbackDescription &rb, QRhiReadbackResult *result)
{
diff --git a/src/gui/rhi/qrhi_p.h b/src/gui/rhi/qrhi_p.h
index d17112a241..8f53808d34 100644
--- a/src/gui/rhi/qrhi_p.h
+++ b/src/gui/rhi/qrhi_p.h
@@ -681,6 +681,11 @@ public:
};
Q_DECLARE_FLAGS(UsageFlags, UsageFlag)
+ struct NativeBuffer {
+ const void *objects[3];
+ int slotCount;
+ };
+
QRhiResource::Type resourceType() const override;
Type type() const { return m_type; }
@@ -694,6 +699,8 @@ public:
virtual bool build() = 0;
+ virtual NativeBuffer nativeBuffer();
+
protected:
QRhiBuffer(QRhiImplementation *rhi, Type type_, UsageFlags usage_, int size_);
Type m_type;
@@ -1430,7 +1437,8 @@ public:
BaseInstance,
TriangleFanTopology,
ReadBackNonUniformBuffer,
- ReadBackNonBaseMipLevel
+ ReadBackNonBaseMipLevel,
+ TexelFetch
};
enum BeginFrameFlag {
@@ -1447,7 +1455,8 @@ public:
TextureSizeMin = 1,
TextureSizeMax,
MaxColorAttachments,
- FramesInFlight
+ FramesInFlight,
+ MaxAsyncReadbackFrames
};
~QRhi();
diff --git a/src/gui/rhi/qrhid3d11.cpp b/src/gui/rhi/qrhid3d11.cpp
index 75b90b6995..f7c7f4a9f2 100644
--- a/src/gui/rhi/qrhid3d11.cpp
+++ b/src/gui/rhi/qrhid3d11.cpp
@@ -464,6 +464,8 @@ bool QRhiD3D11::isFeatureSupported(QRhi::Feature feature) const
return true;
case QRhi::ReadBackNonBaseMipLevel:
return true;
+ case QRhi::TexelFetch:
+ return true;
default:
Q_UNREACHABLE();
return false;
@@ -480,7 +482,13 @@ int QRhiD3D11::resourceLimit(QRhi::ResourceLimit limit) const
case QRhi::MaxColorAttachments:
return 8;
case QRhi::FramesInFlight:
- return 2; // dummy
+ // From our perspective. What D3D does internally is another question
+ // (there could be pipelining, helped f.ex. by our MAP_DISCARD based
+ // uniform buffer update strategy), but that's out of our hands and
+ // does not concern us here.
+ return 1;
+ case QRhi::MaxAsyncReadbackFrames:
+ return 1;
default:
Q_UNREACHABLE();
return 0;
@@ -2378,6 +2386,11 @@ bool QD3D11Buffer::build()
return true;
}
+QRhiBuffer::NativeBuffer QD3D11Buffer::nativeBuffer()
+{
+ return { { &buffer }, 1 };
+}
+
ID3D11UnorderedAccessView *QD3D11Buffer::unorderedAccessView()
{
if (uav)
diff --git a/src/gui/rhi/qrhid3d11_p_p.h b/src/gui/rhi/qrhid3d11_p_p.h
index c3a4021241..04751397f7 100644
--- a/src/gui/rhi/qrhid3d11_p_p.h
+++ b/src/gui/rhi/qrhid3d11_p_p.h
@@ -64,6 +64,7 @@ struct QD3D11Buffer : public QRhiBuffer
~QD3D11Buffer();
void release() override;
bool build() override;
+ QRhiBuffer::NativeBuffer nativeBuffer() override;
ID3D11UnorderedAccessView *unorderedAccessView();
diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp
index 3b6c022399..4a442bc582 100644
--- a/src/gui/rhi/qrhigles2.cpp
+++ b/src/gui/rhi/qrhigles2.cpp
@@ -512,6 +512,8 @@ bool QRhiGles2::create(QRhi::Flags flags)
else
caps.nonBaseLevelFramebufferTexture = true;
+ caps.texelFetch = caps.ctxMajor >= 3; // 3.0 or ES 3.0
+
if (!caps.gles) {
f->glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
f->glEnable(GL_POINT_SPRITE);
@@ -765,6 +767,8 @@ bool QRhiGles2::isFeatureSupported(QRhi::Feature feature) const
return !caps.gles || caps.properMapBuffer;
case QRhi::ReadBackNonBaseMipLevel:
return caps.nonBaseLevelFramebufferTexture;
+ case QRhi::TexelFetch:
+ return caps.texelFetch;
default:
Q_UNREACHABLE();
return false;
@@ -781,7 +785,11 @@ int QRhiGles2::resourceLimit(QRhi::ResourceLimit limit) const
case QRhi::MaxColorAttachments:
return caps.maxDrawBuffers;
case QRhi::FramesInFlight:
- return 2; // dummy
+ // From our perspective. What the GL impl does internally is another
+ // question, but that's out of our hands and does not concern us here.
+ return 1;
+ case QRhi::MaxAsyncReadbackFrames:
+ return 1;
default:
Q_UNREACHABLE();
return 0;
@@ -3293,6 +3301,14 @@ bool QGles2Buffer::build()
return true;
}
+QRhiBuffer::NativeBuffer QGles2Buffer::nativeBuffer()
+{
+ if (m_usage.testFlag(QRhiBuffer::UniformBuffer))
+ return { {}, 0 };
+
+ return { { &buffer }, 1 };
+}
+
QGles2RenderBuffer::QGles2RenderBuffer(QRhiImplementation *rhi, Type type, const QSize &pixelSize,
int sampleCount, QRhiRenderBuffer::Flags flags)
: QRhiRenderBuffer(rhi, type, pixelSize, sampleCount, flags)
diff --git a/src/gui/rhi/qrhigles2_p_p.h b/src/gui/rhi/qrhigles2_p_p.h
index 00caf40118..8b7d01532a 100644
--- a/src/gui/rhi/qrhigles2_p_p.h
+++ b/src/gui/rhi/qrhigles2_p_p.h
@@ -64,6 +64,7 @@ struct QGles2Buffer : public QRhiBuffer
~QGles2Buffer();
void release() override;
bool build() override;
+ QRhiBuffer::NativeBuffer nativeBuffer() override;
GLuint buffer = 0;
GLenum targetForDataOps;
@@ -778,7 +779,8 @@ public:
compute(false),
textureCompareMode(false),
properMapBuffer(false),
- nonBaseLevelFramebufferTexture(false)
+ nonBaseLevelFramebufferTexture(false),
+ texelFetch(false)
{ }
int ctxMajor;
int ctxMinor;
@@ -811,6 +813,7 @@ public:
uint textureCompareMode : 1;
uint properMapBuffer : 1;
uint nonBaseLevelFramebufferTexture : 1;
+ uint texelFetch : 1;
} caps;
QGles2SwapChain *currentSwapChain = nullptr;
QVector<GLint> supportedCompressedFormats;
diff --git a/src/gui/rhi/qrhimetal.mm b/src/gui/rhi/qrhimetal.mm
index 9e8f1ac096..48a562ef1d 100644
--- a/src/gui/rhi/qrhimetal.mm
+++ b/src/gui/rhi/qrhimetal.mm
@@ -562,6 +562,8 @@ bool QRhiMetal::isFeatureSupported(QRhi::Feature feature) const
return true;
case QRhi::ReadBackNonBaseMipLevel:
return true;
+ case QRhi::TexelFetch:
+ return true;
default:
Q_UNREACHABLE();
return false;
@@ -579,6 +581,8 @@ int QRhiMetal::resourceLimit(QRhi::ResourceLimit limit) const
return 8;
case QRhi::FramesInFlight:
return QMTL_FRAMES_IN_FLIGHT;
+ case QRhi::MaxAsyncReadbackFrames:
+ return QMTL_FRAMES_IN_FLIGHT;
default:
Q_UNREACHABLE();
return 0;
@@ -2196,6 +2200,19 @@ bool QMetalBuffer::build()
return true;
}
+QRhiBuffer::NativeBuffer QMetalBuffer::nativeBuffer()
+{
+ if (d->slotted) {
+ NativeBuffer b;
+ Q_ASSERT(sizeof(b.objects) / sizeof(b.objects[0]) >= size_t(QMTL_FRAMES_IN_FLIGHT));
+ for (int i = 0; i < QMTL_FRAMES_IN_FLIGHT; ++i)
+ b.objects[i] = &d->buf[i];
+ b.slotCount = QMTL_FRAMES_IN_FLIGHT;
+ return b;
+ }
+ return { { &d->buf[0] }, 1 };
+}
+
QMetalRenderBuffer::QMetalRenderBuffer(QRhiImplementation *rhi, Type type, const QSize &pixelSize,
int sampleCount, QRhiRenderBuffer::Flags flags)
: QRhiRenderBuffer(rhi, type, pixelSize, sampleCount, flags),
diff --git a/src/gui/rhi/qrhimetal_p_p.h b/src/gui/rhi/qrhimetal_p_p.h
index 58e93e2cdb..212b731b71 100644
--- a/src/gui/rhi/qrhimetal_p_p.h
+++ b/src/gui/rhi/qrhimetal_p_p.h
@@ -65,6 +65,7 @@ struct QMetalBuffer : public QRhiBuffer
~QMetalBuffer();
void release() override;
bool build() override;
+ QRhiBuffer::NativeBuffer nativeBuffer() override;
QMetalBufferData *d;
uint generation = 0;
diff --git a/src/gui/rhi/qrhinull.cpp b/src/gui/rhi/qrhinull.cpp
index 4c59900aa6..8c07e09b32 100644
--- a/src/gui/rhi/qrhinull.cpp
+++ b/src/gui/rhi/qrhinull.cpp
@@ -146,7 +146,9 @@ int QRhiNull::resourceLimit(QRhi::ResourceLimit limit) const
case QRhi::MaxColorAttachments:
return 8;
case QRhi::FramesInFlight:
- return 2; // dummy
+ return 1;
+ case QRhi::MaxAsyncReadbackFrames:
+ return 1;
default:
Q_UNREACHABLE();
return 0;
diff --git a/src/gui/rhi/qrhivulkan.cpp b/src/gui/rhi/qrhivulkan.cpp
index 84ca835392..d378e2a4ad 100644
--- a/src/gui/rhi/qrhivulkan.cpp
+++ b/src/gui/rhi/qrhivulkan.cpp
@@ -3990,6 +3990,8 @@ bool QRhiVulkan::isFeatureSupported(QRhi::Feature feature) const
return true;
case QRhi::ReadBackNonBaseMipLevel:
return true;
+ case QRhi::TexelFetch:
+ return true;
default:
Q_UNREACHABLE();
return false;
@@ -4007,6 +4009,8 @@ int QRhiVulkan::resourceLimit(QRhi::ResourceLimit limit) const
return int(physDevProperties.limits.maxColorAttachments);
case QRhi::FramesInFlight:
return QVK_FRAMES_IN_FLIGHT;
+ case QRhi::MaxAsyncReadbackFrames:
+ return QVK_FRAMES_IN_FLIGHT;
default:
Q_UNREACHABLE();
return 0;
@@ -5181,6 +5185,19 @@ bool QVkBuffer::build()
return true;
}
+QRhiBuffer::NativeBuffer QVkBuffer::nativeBuffer()
+{
+ if (m_type == Dynamic) {
+ NativeBuffer b;
+ Q_ASSERT(sizeof(b.objects) / sizeof(b.objects[0]) >= size_t(QVK_FRAMES_IN_FLIGHT));
+ for (int i = 0; i < QVK_FRAMES_IN_FLIGHT; ++i)
+ b.objects[i] = &buffers[i];
+ b.slotCount = QVK_FRAMES_IN_FLIGHT;
+ return b;
+ }
+ return { { &buffers[0] }, 1 };
+}
+
QVkRenderBuffer::QVkRenderBuffer(QRhiImplementation *rhi, Type type, const QSize &pixelSize,
int sampleCount, Flags flags)
: QRhiRenderBuffer(rhi, type, pixelSize, sampleCount, flags)
diff --git a/src/gui/rhi/qrhivulkan_p_p.h b/src/gui/rhi/qrhivulkan_p_p.h
index d42b83b882..6322882569 100644
--- a/src/gui/rhi/qrhivulkan_p_p.h
+++ b/src/gui/rhi/qrhivulkan_p_p.h
@@ -76,6 +76,7 @@ struct QVkBuffer : public QRhiBuffer
~QVkBuffer();
void release() override;
bool build() override;
+ QRhiBuffer::NativeBuffer nativeBuffer() override;
VkBuffer buffers[QVK_FRAMES_IN_FLIGHT];
QVkAlloc allocations[QVK_FRAMES_IN_FLIGHT];
diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp
index 46cfc79643..64ba01d4e5 100644
--- a/src/gui/text/qtextdocument.cpp
+++ b/src/gui/text/qtextdocument.cpp
@@ -904,6 +904,9 @@ int QTextDocument::lineCount() const
Returns the number of characters of this document.
+ \note As a QTextDocument always contains at least one
+ QChar::ParagraphSeparator, this method will return at least 1.
+
\sa blockCount(), characterAt()
*/
int QTextDocument::characterCount() const
diff --git a/src/gui/text/text.pri b/src/gui/text/text.pri
index 5e97b312f1..464ff3953b 100644
--- a/src/gui/text/text.pri
+++ b/src/gui/text/text.pri
@@ -99,7 +99,7 @@ qtConfig(textodfwriter) {
qtConfig(textmarkdownreader) {
qtConfig(system-textmarkdownreader) {
- QMAKE_USE += libmd4c
+ QMAKE_USE_PRIVATE += libmd4c
} else {
include($$PWD/../../3rdparty/md4c.pri)
}
diff --git a/src/gui/util/qshadergenerator.cpp b/src/gui/util/qshadergenerator.cpp
index 4beed8ed25..1ec25ccd7b 100644
--- a/src/gui/util/qshadergenerator.cpp
+++ b/src/gui/util/qshadergenerator.cpp
@@ -42,6 +42,8 @@
#include "qshaderlanguage_p.h"
#include <QRegularExpression>
+#include <cctype>
+
QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(ShaderGenerator, "ShaderGenerator", QtWarningMsg)
@@ -344,10 +346,9 @@ QByteArray QShaderGenerator::createShaderCode(const QStringList &enabledLayers)
code << QByteArrayLiteral("void main()");
code << QByteArrayLiteral("{");
- const QRegularExpression localToGlobalRegExp(QStringLiteral("^.*\\s+(\\w+)\\s*=\\s*((?:\\w+\\(.*\\))|(?:\\w+)).*;$"));
- const QRegularExpression temporaryVariableToAssignmentRegExp(QStringLiteral("^(.*\\s+(v\\d+))\\s*=\\s*(.*);$"));
+ const QRegularExpression temporaryVariableToAssignmentRegExp(QStringLiteral("([^;]*\\s+(v\\d+))\\s*=\\s*([^;]*);"));
const QRegularExpression temporaryVariableInAssignmentRegExp(QStringLiteral("\\W*(v\\d+)\\W*"));
- const QRegularExpression outputToTemporaryAssignmentRegExp(QStringLiteral("^\\s*(\\w+)\\s*=\\s*(.*);$"));
+ const QRegularExpression statementRegExp(QStringLiteral("\\s*(\\w+)\\s*=\\s*([^;]*);"));
struct Variable;
@@ -457,6 +458,13 @@ QByteArray QShaderGenerator::createShaderCode(const QStringList &enabledLayers)
QByteArray line = node.rule(format).substitution;
const QVector<QShaderNodePort> ports = node.ports();
+ struct VariableReplacement {
+ QByteArray placeholder;
+ QByteArray variable;
+ };
+
+ QVector<VariableReplacement> variableReplacements;
+
// Generate temporary variable names vN
for (const QShaderNodePort &port : ports) {
const QString portName = port.name;
@@ -472,23 +480,65 @@ QByteArray QShaderGenerator::createShaderCode(const QStringList &enabledLayers)
if (variableIndex < 0)
continue;
- const auto placeholder = QByteArray(QByteArrayLiteral("$") + portName.toUtf8());
- const auto variable = QByteArray(QByteArrayLiteral("v") + QByteArray::number(variableIndex));
+ VariableReplacement replacement;
+ replacement.placeholder = QByteArrayLiteral("$") + portName.toUtf8();
+ replacement.variable = QByteArrayLiteral("v") + QByteArray::number(variableIndex);
+
+ variableReplacements.append(std::move(replacement));
+ }
+
+ int begin = 0;
+ while ((begin = line.indexOf('$', begin)) != -1) {
+ int end = begin + 1;
+ char endChar = line.at(end);
+ const int size = line.size();
+ while (end < size && (std::isalnum(endChar) || endChar == '_')) {
+ ++end;
+ endChar = line.at(end);
+ }
+
+ const int placeholderLength = end - begin;
+
+ const QByteArray variableName = line.mid(begin, placeholderLength);
+ const auto replacementIt = std::find_if(variableReplacements.cbegin(), variableReplacements.cend(),
+ [&variableName](const VariableReplacement &replacement) {
+ return variableName == replacement.placeholder;
+ });
- line.replace(placeholder, variable);
+ if (replacementIt != variableReplacements.cend()) {
+ line.replace(begin, placeholderLength, replacementIt->variable);
+ begin += replacementIt->variable.length();
+ } else {
+ begin = end;
+ }
}
// Substitute variable names by generated vN variable names
const QByteArray substitutionedLine = replaceParameters(line, node, format);
- Variable *v = nullptr;
+ QRegularExpressionMatchIterator matches;
switch (node.type()) {
- // Record name of temporary variable that possibly references a global input
- // We will replace the temporary variables by the matching global variables later
- case QShaderNode::Input: {
- const QRegularExpressionMatch match = localToGlobalRegExp.match(QString::fromUtf8(substitutionedLine));
- if (match.hasMatch()) {
+ case QShaderNode::Input:
+ case QShaderNode::Output:
+ matches = statementRegExp.globalMatch(QString::fromUtf8(substitutionedLine));
+ break;
+ case QShaderNode::Function:
+ matches = temporaryVariableToAssignmentRegExp.globalMatch(QString::fromUtf8(substitutionedLine));
+ break;
+ case QShaderNode::Invalid:
+ break;
+ }
+
+ while (matches.hasNext()) {
+ QRegularExpressionMatch match = matches.next();
+
+ Variable *v = nullptr;
+
+ switch (node.type()) {
+ // Record name of temporary variable that possibly references a global input
+ // We will replace the temporary variables by the matching global variables later
+ case QShaderNode::Input: {
const QString localVariable = match.captured(1);
const QString globalVariable = match.captured(2);
@@ -499,13 +549,10 @@ QByteArray QShaderGenerator::createShaderCode(const QStringList &enabledLayers)
Assignment assignment;
assignment.expression = globalVariable;
v->assignment = assignment;
+ break;
}
- break;
- }
- case QShaderNode::Function: {
- const QRegularExpressionMatch match = temporaryVariableToAssignmentRegExp.match(QString::fromUtf8(substitutionedLine));
- if (match.hasMatch()) {
+ case QShaderNode::Function: {
const QString localVariableDeclaration = match.captured(1);
const QString localVariableName = match.captured(2);
const QString assignmentContent = match.captured(3);
@@ -518,13 +565,10 @@ QByteArray QShaderGenerator::createShaderCode(const QStringList &enabledLayers)
// Find variables that may be referenced in the assignment
gatherTemporaryVariablesFromAssignment(v, assignmentContent);
+ break;
}
- break;
- }
- case QShaderNode::Output: {
- const QRegularExpressionMatch match = outputToTemporaryAssignmentRegExp.match(QString::fromUtf8(substitutionedLine));
- if (match.hasMatch()) {
+ case QShaderNode::Output: {
const QString outputDeclaration = match.captured(1);
const QString assignmentContent = match.captured(2);
@@ -539,17 +583,17 @@ QByteArray QShaderGenerator::createShaderCode(const QStringList &enabledLayers)
// Find variables that may be referenced in the assignment
gatherTemporaryVariablesFromAssignment(v, assignmentContent);
+ break;
+ }
+ case QShaderNode::Invalid:
+ break;
}
- break;
- }
- case QShaderNode::Invalid:
- break;
- }
- LineContent lineContent;
- lineContent.rawContent = QByteArray(QByteArrayLiteral(" ") + substitutionedLine);
- lineContent.var = v;
- lines << lineContent;
+ LineContent lineContent;
+ lineContent.rawContent = QByteArray(QByteArrayLiteral(" ") + substitutionedLine);
+ lineContent.var = v;
+ lines << lineContent;
+ }
}
// Go through all lines
diff --git a/src/gui/util/qshadergraph.cpp b/src/gui/util/qshadergraph.cpp
index b05b710713..611bb4b938 100644
--- a/src/gui/util/qshadergraph.cpp
+++ b/src/gui/util/qshadergraph.cpp
@@ -44,13 +44,20 @@ QT_BEGIN_NAMESPACE
namespace
{
- QVector<QShaderNode> copyOutputNodes(const QVector<QShaderNode> &nodes)
+ QVector<QShaderNode> copyOutputNodes(const QVector<QShaderNode> &nodes, const QVector<QShaderGraph::Edge> &edges)
{
auto res = QVector<QShaderNode>();
std::copy_if(nodes.cbegin(), nodes.cend(),
std::back_inserter(res),
- [] (const QShaderNode &node) {
- return node.type() == QShaderNode::Output;
+ [&edges] (const QShaderNode &node) {
+ return node.type() == QShaderNode::Output ||
+ (node.type() == QShaderNode::Function &&
+ !std::any_of(edges.cbegin(),
+ edges.cend(),
+ [&node] (const QShaderGraph::Edge &edge) {
+ return edge.sourceNodeUuid ==
+ node.uuid();
+ }));
});
return res;
}
@@ -116,6 +123,50 @@ namespace
}
return targetStatement;
}
+
+ void removeNodesWithUnboundInputs(QVector<QShaderGraph::Statement> &statements,
+ const QVector<QShaderGraph::Edge> &allEdges)
+ {
+ // A node is invalid if any of its input ports is disconected
+ // or connected to the output port of another invalid node.
+
+ // Keeps track of the edges from the nodes we know to be valid
+ // to unvisited nodes
+ auto currentEdges = QVector<QShaderGraph::Edge>();
+
+ statements.erase(std::remove_if(statements.begin(),
+ statements.end(),
+ [&currentEdges, &allEdges] (const QShaderGraph::Statement &statement) {
+ const QShaderNode &node = statement.node;
+ const QVector<QShaderGraph::Edge> outgoing = outgoingEdges(currentEdges, node.uuid());
+ const QVector<QShaderNodePort> ports = node.ports();
+
+ bool allInputsConnected = true;
+ for (const QShaderNodePort &port : node.ports()) {
+ if (port.direction == QShaderNodePort::Output)
+ continue;
+
+ const auto edgeIt = std::find_if(outgoing.cbegin(),
+ outgoing.cend(),
+ [&port] (const QShaderGraph::Edge &edge) {
+ return edge.targetPortName == port.name;
+ });
+
+ if (edgeIt != outgoing.cend())
+ currentEdges.removeAll(*edgeIt);
+ else
+ allInputsConnected = false;
+ }
+
+ if (allInputsConnected) {
+ const QVector<QShaderGraph::Edge> incoming = incomingEdges(allEdges, node.uuid());
+ currentEdges.append(incoming);
+ }
+
+ return !allInputsConnected;
+ }),
+ statements.end());
+ }
}
QUuid QShaderGraph::Statement::uuid() const noexcept
@@ -210,8 +261,8 @@ QVector<QShaderGraph::Statement> QShaderGraph::createStatements(const QStringLis
auto result = QVector<Statement>();
QVector<Edge> currentEdges = enabledEdges;
- QVector<QUuid> currentUuids = [enabledNodes] {
- const QVector<QShaderNode> inputs = copyOutputNodes(enabledNodes);
+ QVector<QUuid> currentUuids = [enabledNodes, enabledEdges] {
+ const QVector<QShaderNode> inputs = copyOutputNodes(enabledNodes, enabledEdges);
auto res = QVector<QUuid>();
std::transform(inputs.cbegin(), inputs.cend(),
std::back_inserter(res),
@@ -241,6 +292,9 @@ QVector<QShaderGraph::Statement> QShaderGraph::createStatements(const QStringLis
}
std::reverse(result.begin(), result.end());
+
+ removeNodesWithUnboundInputs(result, enabledEdges);
+
return result;
}
diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp
index a3c8172a70..65c2ae3054 100644
--- a/src/network/access/qhttpnetworkconnectionchannel.cpp
+++ b/src/network/access/qhttpnetworkconnectionchannel.cpp
@@ -1098,6 +1098,7 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket
if (reply) {
reply->d_func()->errorString = errorString;
+ reply->d_func()->httpErrorCode = errorCode;
emit reply->finishedWithError(errorCode, errorString);
reply = nullptr;
if (protocolHandler)
diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp
index 1ba52ac6d6..78413062b4 100644
--- a/src/network/access/qhttpnetworkreply.cpp
+++ b/src/network/access/qhttpnetworkreply.cpp
@@ -158,6 +158,11 @@ QString QHttpNetworkReply::errorString() const
return d_func()->errorString;
}
+QNetworkReply::NetworkError QHttpNetworkReply::errorCode() const
+{
+ return d_func()->httpErrorCode;
+}
+
QString QHttpNetworkReply::reasonPhrase() const
{
return d_func()->reasonPhrase;
diff --git a/src/network/access/qhttpnetworkreply_p.h b/src/network/access/qhttpnetworkreply_p.h
index 82128f656e..4638d056de 100644
--- a/src/network/access/qhttpnetworkreply_p.h
+++ b/src/network/access/qhttpnetworkreply_p.h
@@ -115,6 +115,8 @@ public:
QString errorString() const;
void setErrorString(const QString &error);
+ QNetworkReply::NetworkError errorCode() const;
+
QString reasonPhrase() const;
qint64 bytesAvailable() const;
@@ -255,6 +257,7 @@ public:
qint64 removedContentLength;
QPointer<QHttpNetworkConnection> connection;
QPointer<QHttpNetworkConnectionChannel> connectionChannel;
+ QNetworkReply::NetworkError httpErrorCode = QNetworkReply::NoError;
bool autoDecompress;
diff --git a/src/network/access/qhttpthreaddelegate.cpp b/src/network/access/qhttpthreaddelegate.cpp
index 5a0940aa24..fa03bf7a11 100644
--- a/src/network/access/qhttpthreaddelegate.cpp
+++ b/src/network/access/qhttpthreaddelegate.cpp
@@ -417,6 +417,12 @@ void QHttpThreadDelegate::startRequest()
connect(httpReply, SIGNAL(cacheCredentials(QHttpNetworkRequest,QAuthenticator*)),
this, SLOT(cacheCredentialsSlot(QHttpNetworkRequest,QAuthenticator*)));
+ if (httpReply->errorCode() != QNetworkReply::NoError) {
+ if (synchronous)
+ synchronousFinishedWithErrorSlot(httpReply->errorCode(), httpReply->errorString());
+ else
+ finishedWithErrorSlot(httpReply->errorCode(), httpReply->errorString());
+ }
}
// This gets called from the user thread or by the synchronous HTTP timeout timer
diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp
index 38807d3cda..85f065223a 100644
--- a/src/network/access/qnetworkaccessmanager.cpp
+++ b/src/network/access/qnetworkaccessmanager.cpp
@@ -220,27 +220,6 @@ static void ensureInitialized()
can be:
\snippet code/src_network_access_qnetworkaccessmanager.cpp 1
- \section1 Network and Roaming Support
-
- With the addition of the \l {Bearer Management} API to Qt 4.7
- QNetworkAccessManager gained the ability to manage network connections.
- QNetworkAccessManager can start the network interface if the device is
- offline and terminates the interface if the current process is the last
- one to use the uplink. Note that some platforms utilize grace periods from
- when the last application stops using a uplink until the system actually
- terminates the connectivity link. Roaming is equally transparent. Any
- queued/pending network requests are automatically transferred to the new
- access point.
-
- Clients wanting to utilize this feature should not require any changes. In fact
- it is likely that existing platform specific connection code can simply be
- removed from the application.
-
- \note The network and roaming support in QNetworkAccessManager is conditional
- upon the platform supporting connection management. The
- \l QNetworkConfigurationManager::NetworkSessionRequired can be used to
- detect whether QNetworkAccessManager utilizes this feature.
-
\sa QNetworkRequest, QNetworkReply, QNetworkProxy
*/
@@ -1475,7 +1454,7 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera
// immediately set 'networkAccessible' even before we start
// the monitor.
#ifdef QT_NO_BEARERMANAGEMENT
- if (d->networkAccessible
+ if (!d->networkAccessible
#else
if (d->networkAccessible == NotAccessible
#endif // QT_NO_BEARERMANAGEMENT
diff --git a/src/network/access/qnetworkaccessmanager.h b/src/network/access/qnetworkaccessmanager.h
index cfb75f0f90..5194afb1be 100644
--- a/src/network/access/qnetworkaccessmanager.h
+++ b/src/network/access/qnetworkaccessmanager.h
@@ -170,7 +170,7 @@ public:
void setAutoDeleteReplies(bool autoDelete);
int transferTimeout() const;
- void setTransferTimeout(int timeout = QNetworkRequest::TransferTimeoutPreset);
+ void setTransferTimeout(int timeout = QNetworkRequest::DefaultTransferTimeoutConstant);
Q_SIGNALS:
#ifndef QT_NO_NETWORKPROXY
diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp
index 473aa42e1e..4765fdc30e 100644
--- a/src/network/access/qnetworkrequest.cpp
+++ b/src/network/access/qnetworkrequest.cpp
@@ -414,9 +414,9 @@ QT_BEGIN_NAMESPACE
A constant that can be used for enabling transfer
timeouts with a preset value.
- \value TransferTimeoutPreset The transfer timeout in milliseconds.
- Used if setTimeout() is called
- without an argument.
+ \value DefaultTransferTimeoutConstant The transfer timeout in milliseconds.
+ Used if setTimeout() is called
+ without an argument.
*/
class QNetworkRequestPrivate: public QSharedData, public QNetworkHeadersPrivate
diff --git a/src/network/access/qnetworkrequest.h b/src/network/access/qnetworkrequest.h
index cb15ca5aa5..035b5b378a 100644
--- a/src/network/access/qnetworkrequest.h
+++ b/src/network/access/qnetworkrequest.h
@@ -127,7 +127,7 @@ public:
};
enum TransferTimeoutConstant {
- TransferTimeoutPreset = 30000
+ DefaultTransferTimeoutConstant = 30000
};
QNetworkRequest();
@@ -182,7 +182,7 @@ public:
void setHttp2Configuration(const QHttp2Configuration &configuration);
int transferTimeout() const;
- void setTransferTimeout(int timeout = TransferTimeoutPreset);
+ void setTransferTimeout(int timeout = DefaultTransferTimeoutConstant);
#endif // QT_CONFIG(http) || defined(Q_CLANG_QDOC)
private:
QSharedDataPointer<QNetworkRequestPrivate> d;
diff --git a/src/network/doc/src/network-programming.qdoc b/src/network/doc/src/network-programming.qdoc
index ce99af034b..654227f971 100644
--- a/src/network/doc/src/network-programming.qdoc
+++ b/src/network/doc/src/network-programming.qdoc
@@ -261,29 +261,4 @@
by passing a factory to QNetworkProxyFactory::setApplicationProxyFactory()
and a custom proxying policy can be created by subclassing
QNetworkProxyFactory; see the class documentation for details.
-
- \section1 Bearer Management Support
-
- Bearer Management controls the connectivity state of the device such that
- the application can start or stop network interfaces and roam
- transparently between access points.
-
- The QNetworkConfigurationManager class manages the list of network
- configurations known to the device. A network configuration describes the
- set of parameters used to start a network interface and is represented by
- the QNetworkConfiguration class.
-
- A network interface is started by openning a QNetworkSession based on a
- given network configuration. In most situations creating a network session
- based on the platform specified default network configuration is
- appropriate. The default network configuration is returned by the
- QNetworkConfigurationManager::defaultConfiguration() function.
-
- On some platforms it is a platform requirement that the application open a
- network session before any network operations can be performed. This can be
- tested by the presents of the
- QNetworkConfigurationManager::NetworkSessionRequired flag in the value
- returned by the QNetworkConfigurationManager::capabilities() function.
-
- \sa {Bearer Management}
*/
diff --git a/src/network/doc/src/qtnetwork.qdoc b/src/network/doc/src/qtnetwork.qdoc
index c931a1c19f..85a3c198a0 100644
--- a/src/network/doc/src/qtnetwork.qdoc
+++ b/src/network/doc/src/qtnetwork.qdoc
@@ -54,7 +54,6 @@
applications with networking capabilities.
\list
\li \l{Network Programming with Qt} - Programming applications with networking capabilities
- \li \l{Bearer Management} - An API to control the system's connectivity state
\li \l{Secure Sockets Layer (SSL) Classes} - Classes for secure communication over network sockets
\endlist
diff --git a/src/network/kernel/qnetconmonitor_win.cpp b/src/network/kernel/qnetconmonitor_win.cpp
index 1566e7f914..59b6cd5b66 100644
--- a/src/network/kernel/qnetconmonitor_win.cpp
+++ b/src/network/kernel/qnetconmonitor_win.cpp
@@ -163,11 +163,14 @@ private:
ComPtr<QNetworkConnectionEvents> connectionEvents;
// We can assume we have access to internet/subnet when this class is created because
// connection has already been established to the peer:
- NLM_CONNECTIVITY connectivity =
- NLM_CONNECTIVITY(NLM_CONNECTIVITY_IPV4_INTERNET | NLM_CONNECTIVITY_IPV6_INTERNET
- | NLM_CONNECTIVITY_IPV4_SUBNET | NLM_CONNECTIVITY_IPV6_SUBNET);
+ NLM_CONNECTIVITY connectivity = NLM_CONNECTIVITY(
+ NLM_CONNECTIVITY_IPV4_INTERNET | NLM_CONNECTIVITY_IPV6_INTERNET
+ | NLM_CONNECTIVITY_IPV4_SUBNET | NLM_CONNECTIVITY_IPV6_SUBNET
+ | NLM_CONNECTIVITY_IPV4_LOCALNETWORK | NLM_CONNECTIVITY_IPV6_LOCALNETWORK
+ | NLM_CONNECTIVITY_IPV4_NOTRAFFIC | NLM_CONNECTIVITY_IPV6_NOTRAFFIC);
bool sameSubnet = false;
+ bool isLinkLocal = false;
bool monitoring = false;
bool comInitFailed = false;
bool remoteIsIPv6 = false;
@@ -370,6 +373,7 @@ bool QNetworkConnectionMonitorPrivate::setTargets(const QHostAddress &local,
return false;
}
sameSubnet = remote.isInSubnet(local, it->prefixLength());
+ isLinkLocal = remote.isLinkLocal() && local.isLinkLocal();
remoteIsIPv6 = remote.protocol() == QAbstractSocket::IPv6Protocol;
return connectionEvents->setTarget(iface);
@@ -461,9 +465,28 @@ void QNetworkConnectionMonitor::stopMonitoring()
bool QNetworkConnectionMonitor::isReachable()
{
Q_D(QNetworkConnectionMonitor);
- NLM_CONNECTIVITY required = d->sameSubnet
- ? (d->remoteIsIPv6 ? NLM_CONNECTIVITY_IPV6_SUBNET : NLM_CONNECTIVITY_IPV4_SUBNET)
- : (d->remoteIsIPv6 ? NLM_CONNECTIVITY_IPV6_INTERNET : NLM_CONNECTIVITY_IPV4_INTERNET);
+
+ const NLM_CONNECTIVITY RequiredSameSubnetIPv6 =
+ NLM_CONNECTIVITY(NLM_CONNECTIVITY_IPV6_SUBNET | NLM_CONNECTIVITY_IPV6_LOCALNETWORK
+ | NLM_CONNECTIVITY_IPV6_INTERNET);
+ const NLM_CONNECTIVITY RequiredSameSubnetIPv4 =
+ NLM_CONNECTIVITY(NLM_CONNECTIVITY_IPV4_SUBNET | NLM_CONNECTIVITY_IPV4_LOCALNETWORK
+ | NLM_CONNECTIVITY_IPV4_INTERNET);
+
+ NLM_CONNECTIVITY required;
+ if (d->isLinkLocal) {
+ required = NLM_CONNECTIVITY(
+ d->remoteIsIPv6 ? NLM_CONNECTIVITY_IPV6_NOTRAFFIC | RequiredSameSubnetIPv6
+ : NLM_CONNECTIVITY_IPV4_NOTRAFFIC | RequiredSameSubnetIPv4);
+ } else if (d->sameSubnet) {
+ required =
+ NLM_CONNECTIVITY(d->remoteIsIPv6 ? RequiredSameSubnetIPv6 : RequiredSameSubnetIPv4);
+
+ } else {
+ required = NLM_CONNECTIVITY(d->remoteIsIPv6 ? NLM_CONNECTIVITY_IPV6_INTERNET
+ : NLM_CONNECTIVITY_IPV4_INTERNET);
+ }
+
return d_func()->connectivity & required;
}
@@ -695,7 +718,8 @@ bool QNetworkStatusMonitor::isNetworkAccessible()
{
return d_func()->connectivity
& (NLM_CONNECTIVITY_IPV4_INTERNET | NLM_CONNECTIVITY_IPV6_INTERNET
- | NLM_CONNECTIVITY_IPV4_SUBNET | NLM_CONNECTIVITY_IPV6_SUBNET);
+ | NLM_CONNECTIVITY_IPV4_SUBNET | NLM_CONNECTIVITY_IPV6_SUBNET
+ | NLM_CONNECTIVITY_IPV4_LOCALNETWORK | NLM_CONNECTIVITY_IPV6_LOCALNETWORK);
}
bool QNetworkStatusMonitor::isEnabled()
diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp
index 3d88c0337d..5f1ff2fcb8 100644
--- a/src/network/socket/qabstractsocket.cpp
+++ b/src/network/socket/qabstractsocket.cpp
@@ -1465,13 +1465,8 @@ QAbstractSocket::QAbstractSocket(SocketType socketType,
\sa socketType(), QTcpSocket, QUdpSocket
*/
QAbstractSocket::QAbstractSocket(SocketType socketType, QObject *parent)
- : QIODevice(*new QAbstractSocketPrivate, parent)
+ : QAbstractSocket(socketType, *new QAbstractSocketPrivate, parent)
{
- Q_D(QAbstractSocket);
-#if defined(QABSTRACTSOCKET_DEBUG)
- qDebug("QAbstractSocket::QAbstractSocket(%p)", parent);
-#endif
- d->socketType = socketType;
}
/*!
diff --git a/src/network/socket/qlocalsocket.cpp b/src/network/socket/qlocalsocket.cpp
index 38e47d6e26..18f400fe0b 100644
--- a/src/network/socket/qlocalsocket.cpp
+++ b/src/network/socket/qlocalsocket.cpp
@@ -51,7 +51,7 @@ QT_BEGIN_NAMESPACE
On Windows this is a named pipe and on Unix this is a local domain socket.
- If an error occurs, socketError() returns the type of error, and
+ If an error occurs, error() returns the type of error, and
errorString() can be called to get a human readable description
of what happened.
diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp
index dd115c33dc..2581fc048e 100644
--- a/src/network/socket/qnativesocketengine_win.cpp
+++ b/src/network/socket/qnativesocketengine_win.cpp
@@ -590,7 +590,8 @@ bool QNativeSocketEnginePrivate::fetchConnectionParameters()
// local address of the socket which bound on both IPv4 and IPv6 interfaces.
// This address does not match to any special address and should not be used
// to send the data. So, replace it with QHostAddress::Any.
- if (socketProtocol == QAbstractSocket::IPv6Protocol) {
+ const uchar ipv6MappedNet[] = {0,0,0,0, 0,0,0,0, 0,0,0xff,0xff, 0,0,0,0};
+ if (localAddress.isInSubnet(QHostAddress(ipv6MappedNet), 128 - 32)) {
bool ok = false;
const quint32 localIPv4 = localAddress.toIPv4Address(&ok);
if (ok && localIPv4 == INADDR_ANY) {
diff --git a/src/platformsupport/windowsuiautomation/uiapropertyids_p.h b/src/platformsupport/windowsuiautomation/uiapropertyids_p.h
index 74e84147f6..9c14a35271 100644
--- a/src/platformsupport/windowsuiautomation/uiapropertyids_p.h
+++ b/src/platformsupport/windowsuiautomation/uiapropertyids_p.h
@@ -219,5 +219,6 @@
#define UIA_CenterPointPropertyId 30165
#define UIA_RotationPropertyId 30166
#define UIA_SizePropertyId 30167
+#define UIA_IsDialogPropertyId 30174
#endif
diff --git a/src/platformsupport/windowsuiautomation/uiaserverinterfaces_p.h b/src/platformsupport/windowsuiautomation/uiaserverinterfaces_p.h
index fd39b6ee33..fde16206da 100644
--- a/src/platformsupport/windowsuiautomation/uiaserverinterfaces_p.h
+++ b/src/platformsupport/windowsuiautomation/uiaserverinterfaces_p.h
@@ -383,4 +383,21 @@ __CRT_UUID_DECL(IWindowProvider, 0x987df77b, 0xdb06, 0x4d77, 0x8f,0x8a, 0x86,0xa
#endif
#endif
+
+#ifndef __IExpandCollapseProvider_INTERFACE_DEFINED__
+#define __IExpandCollapseProvider_INTERFACE_DEFINED__
+DEFINE_GUID(IID_IExpandCollapseProvider, 0xd847d3a5, 0xcab0, 0x4a98, 0x8c,0x32, 0xec,0xb4,0x5c,0x59,0xad,0x24);
+MIDL_INTERFACE("d847d3a5-cab0-4a98-8c32-ecb45c59ad24")
+IExpandCollapseProvider : public IUnknown
+{
+public:
+ virtual HRESULT STDMETHODCALLTYPE Expand() = 0;
+ virtual HRESULT STDMETHODCALLTYPE Collapse() = 0;
+ virtual HRESULT STDMETHODCALLTYPE get_ExpandCollapseState(__RPC__out enum ExpandCollapseState *pRetVal) = 0;
+};
+#ifdef __CRT_UUID_DECL
+__CRT_UUID_DECL(IExpandCollapseProvider, 0xd847d3a5, 0xcab0, 0x4a98, 0x8c,0x32, 0xec,0xb4,0x5c,0x59,0xad,0x24)
+#endif
+#endif
+
#endif
diff --git a/src/platformsupport/windowsuiautomation/uiatypes_p.h b/src/platformsupport/windowsuiautomation/uiatypes_p.h
index 8ef71843a3..afbc957094 100644
--- a/src/platformsupport/windowsuiautomation/uiatypes_p.h
+++ b/src/platformsupport/windowsuiautomation/uiatypes_p.h
@@ -155,6 +155,13 @@ enum WindowInteractionState {
WindowInteractionState_NotResponding = 4
};
+enum ExpandCollapseState {
+ ExpandCollapseState_Collapsed = 0,
+ ExpandCollapseState_Expanded = 1,
+ ExpandCollapseState_PartiallyExpanded = 2,
+ ExpandCollapseState_LeafNode = 3
+};
+
struct UiaRect {
double left;
double top;
diff --git a/src/plugins/platforms/android/qandroidplatformfiledialoghelper.cpp b/src/plugins/platforms/android/qandroidplatformfiledialoghelper.cpp
index fb979ab6cc..7b5f2f16f8 100644
--- a/src/plugins/platforms/android/qandroidplatformfiledialoghelper.cpp
+++ b/src/plugins/platforms/android/qandroidplatformfiledialoghelper.cpp
@@ -40,7 +40,6 @@
#include "qandroidplatformfiledialoghelper.h"
#include <androidjnimain.h>
-#include <private/qjni_p.h>
#include <jni.h>
QT_BEGIN_NAMESPACE
@@ -50,9 +49,11 @@ namespace QtAndroidFileDialogHelper {
#define RESULT_OK -1
#define REQUEST_CODE 1305 // Arbitrary
+const char JniIntentClass[] = "android/content/Intent";
+
QAndroidPlatformFileDialogHelper::QAndroidPlatformFileDialogHelper()
- : QPlatformFileDialogHelper()
- , m_selectedFile()
+ : QPlatformFileDialogHelper(),
+ m_activity(QtAndroid::activity())
{
}
@@ -61,92 +62,165 @@ bool QAndroidPlatformFileDialogHelper::handleActivityResult(jint requestCode, ji
if (requestCode != REQUEST_CODE)
return false;
- if (resultCode == RESULT_OK) {
- const QJNIObjectPrivate intent = QJNIObjectPrivate::fromLocalRef(data);
- const QJNIObjectPrivate uri = intent.callObjectMethod("getData", "()Landroid/net/Uri;");
- const QString uriStr = uri.callObjectMethod("toString", "()Ljava/lang/String;").toString();
- m_selectedFile = QUrl(uriStr);
- Q_EMIT fileSelected(m_selectedFile);
- Q_EMIT accept();
- } else {
+ if (resultCode != RESULT_OK) {
Q_EMIT reject();
+ return true;
}
- return true;
-}
-
-bool QAndroidPlatformFileDialogHelper::show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent)
-{
- Q_UNUSED(windowFlags)
- Q_UNUSED(windowModality)
- Q_UNUSED(parent)
-
- if (options()->fileMode() != QFileDialogOptions::FileMode::ExistingFile)
- return false;
+ const QJNIObjectPrivate intent = QJNIObjectPrivate::fromLocalRef(data);
- QtAndroidPrivate::registerActivityResultListener(this);
+ const QJNIObjectPrivate uri = intent.callObjectMethod("getData", "()Landroid/net/Uri;");
+ if (uri.isValid()) {
+ takePersistableUriPermission(uri);
+ m_selectedFile.append(QUrl(uri.toString()));
+ Q_EMIT fileSelected(m_selectedFile.first());
+ Q_EMIT accept();
- const QJNIObjectPrivate ACTION_OPEN_DOCUMENT = QJNIObjectPrivate::getStaticObjectField("android/content/Intent", "ACTION_OPEN_DOCUMENT", "Ljava/lang/String;");
- QJNIObjectPrivate intent("android/content/Intent", "(Ljava/lang/String;)V", ACTION_OPEN_DOCUMENT.object());
- const QJNIObjectPrivate CATEGORY_OPENABLE = QJNIObjectPrivate::getStaticObjectField("android/content/Intent", "CATEGORY_OPENABLE", "Ljava/lang/String;");
- intent.callObjectMethod("addCategory", "(Ljava/lang/String;)Landroid/content/Intent;", CATEGORY_OPENABLE.object());
- intent.callObjectMethod("setType", "(Ljava/lang/String;)Landroid/content/Intent;", QJNIObjectPrivate::fromString(QStringLiteral("*/*")).object());
+ return true;
+ }
- const QJNIObjectPrivate activity(QtAndroid::activity());
- activity.callMethod<void>("startActivityForResult", "(Landroid/content/Intent;I)V", intent.object(), REQUEST_CODE);
+ const QJNIObjectPrivate uriClipData =
+ intent.callObjectMethod("getClipData", "()Landroid/content/ClipData;");
+ if (uriClipData.isValid()) {
+ const int size = uriClipData.callMethod<jint>("getItemCount");
+ for (int i = 0; i < size; ++i) {
+ QJNIObjectPrivate item = uriClipData.callObjectMethod(
+ "getItemAt", "(I)Landroid/content/ClipData$Item;", i);
+
+ QJNIObjectPrivate itemUri = item.callObjectMethod("getUri", "()Landroid/net/Uri;");
+ takePersistableUriPermission(itemUri);
+ m_selectedFile.append(itemUri.toString());
+ Q_EMIT filesSelected(m_selectedFile);
+ Q_EMIT accept();
+ }
+ }
return true;
}
-void QAndroidPlatformFileDialogHelper::exec()
+void QAndroidPlatformFileDialogHelper::takePersistableUriPermission(const QJNIObjectPrivate &uri)
{
- m_eventLoop.exec(QEventLoop::DialogExec);
+ int modeFlags = QJNIObjectPrivate::getStaticField<jint>(
+ JniIntentClass, "FLAG_GRANT_READ_URI_PERMISSION");
+
+ if (options()->acceptMode() == QFileDialogOptions::AcceptSave) {
+ modeFlags |= QJNIObjectPrivate::getStaticField<jint>(
+ JniIntentClass, "FLAG_GRANT_WRITE_URI_PERMISSION");
+ }
+
+ QJNIObjectPrivate contentResolver = m_activity.callObjectMethod(
+ "getContentResolver", "()Landroid/content/ContentResolver;");
+ contentResolver.callMethod<void>("takePersistableUriPermission", "(Landroid/net/Uri;I)V",
+ uri.object(), modeFlags);
}
-void QAndroidPlatformFileDialogHelper::hide()
+void QAndroidPlatformFileDialogHelper::setLocalFilesOnly(bool localOnly)
{
- if (m_eventLoop.isRunning())
- m_eventLoop.exit();
- QtAndroidPrivate::unregisterActivityResultListener(this);
+ const QJNIObjectPrivate extraLocalOnly = QJNIObjectPrivate::getStaticObjectField(
+ JniIntentClass, "EXTRA_LOCAL_ONLY", "Ljava/lang/String;");
+ m_intent.callObjectMethod("putExtra", "(Ljava/lang/String;Z)Landroid/content/Intent;",
+ extraLocalOnly.object(), localOnly);
}
-QString QAndroidPlatformFileDialogHelper::selectedNameFilter() const
+void QAndroidPlatformFileDialogHelper::setIntentTitle(const QString &title)
{
- return QString();
+ const QJNIObjectPrivate extraTitle = QJNIObjectPrivate::getStaticObjectField(
+ JniIntentClass, "EXTRA_TITLE", "Ljava/lang/String;");
+ m_intent.callObjectMethod("putExtra",
+ "(Ljava/lang/String;Ljava/lang/String;)Landroid/content/Intent;",
+ extraTitle.object(), QJNIObjectPrivate::fromString(title).object());
}
-void QAndroidPlatformFileDialogHelper::selectNameFilter(const QString &filter)
+void QAndroidPlatformFileDialogHelper::setOpenableCategory()
{
- Q_UNUSED(filter)
+ const QJNIObjectPrivate CATEGORY_OPENABLE = QJNIObjectPrivate::getStaticObjectField(
+ JniIntentClass, "CATEGORY_OPENABLE", "Ljava/lang/String;");
+ m_intent.callObjectMethod("addCategory", "(Ljava/lang/String;)Landroid/content/Intent;",
+ CATEGORY_OPENABLE.object());
}
-void QAndroidPlatformFileDialogHelper::setFilter()
+void QAndroidPlatformFileDialogHelper::setAllowMultipleSelections(bool allowMultiple)
{
+ const QJNIObjectPrivate allowMultipleSelections = QJNIObjectPrivate::getStaticObjectField(
+ JniIntentClass, "EXTRA_ALLOW_MULTIPLE", "Ljava/lang/String;");
+ m_intent.callObjectMethod("putExtra", "(Ljava/lang/String;Z)Landroid/content/Intent;",
+ allowMultipleSelections.object(), allowMultiple);
}
-QList<QUrl> QAndroidPlatformFileDialogHelper::selectedFiles() const
+void QAndroidPlatformFileDialogHelper::setMimeTypes()
{
- return {m_selectedFile};
+ m_intent.callObjectMethod("setType", "(Ljava/lang/String;)Landroid/content/Intent;",
+ QJNIObjectPrivate::fromString("*/*").object());
+
+ const QJNIObjectPrivate extraMimeType = QJNIObjectPrivate::getStaticObjectField(
+ JniIntentClass, "EXTRA_MIME_TYPES", "Ljava/lang/String;");
+ for (const QString &type : options()->mimeTypeFilters()) {
+ m_intent.callObjectMethod(
+ "putExtra", "(Ljava/lang/String;Ljava/lang/String;)Landroid/content/Intent;",
+ extraMimeType.object(), QJNIObjectPrivate::fromString(type).object());
+ }
}
-void QAndroidPlatformFileDialogHelper::selectFile(const QUrl &file)
+QJNIObjectPrivate QAndroidPlatformFileDialogHelper::getFileDialogIntent(const QString &intentType)
{
- Q_UNUSED(file)
+ const QJNIObjectPrivate ACTION_OPEN_DOCUMENT = QJNIObjectPrivate::getStaticObjectField(
+ JniIntentClass, intentType.toLatin1(), "Ljava/lang/String;");
+ return QJNIObjectPrivate(JniIntentClass, "(Ljava/lang/String;)V",
+ ACTION_OPEN_DOCUMENT.object());
}
-QUrl QAndroidPlatformFileDialogHelper::directory() const
+bool QAndroidPlatformFileDialogHelper::show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent)
{
- return QUrl();
+ Q_UNUSED(windowFlags)
+ Q_UNUSED(windowModality)
+ Q_UNUSED(parent)
+
+ bool isDirDialog = false;
+
+ if (options()->acceptMode() == QFileDialogOptions::AcceptSave) {
+ m_intent = getFileDialogIntent("ACTION_CREATE_DOCUMENT");
+ } else if (options()->acceptMode() == QFileDialogOptions::AcceptOpen) {
+ switch (options()->fileMode()) {
+ case QFileDialogOptions::FileMode::DirectoryOnly:
+ case QFileDialogOptions::FileMode::Directory:
+ m_intent = getFileDialogIntent("ACTION_OPEN_DOCUMENT_TREE");
+ isDirDialog = true;
+ break;
+ case QFileDialogOptions::FileMode::ExistingFiles:
+ m_intent = getFileDialogIntent("ACTION_OPEN_DOCUMENT");
+ setAllowMultipleSelections(true);
+ break;
+ case QFileDialogOptions::FileMode::AnyFile:
+ case QFileDialogOptions::FileMode::ExistingFile:
+ m_intent = getFileDialogIntent("ACTION_OPEN_DOCUMENT");
+ break;
+ }
+ }
+
+ if (!isDirDialog) {
+ setOpenableCategory();
+ setMimeTypes();
+ }
+
+ setIntentTitle(options()->windowTitle());
+ setLocalFilesOnly(true);
+
+ QtAndroidPrivate::registerActivityResultListener(this);
+ m_activity.callMethod<void>("startActivityForResult", "(Landroid/content/Intent;I)V",
+ m_intent.object(), REQUEST_CODE);
+ return true;
}
-void QAndroidPlatformFileDialogHelper::setDirectory(const QUrl &directory)
+void QAndroidPlatformFileDialogHelper::hide()
{
- Q_UNUSED(directory)
+ if (m_eventLoop.isRunning())
+ m_eventLoop.exit();
+ QtAndroidPrivate::unregisterActivityResultListener(this);
}
-bool QAndroidPlatformFileDialogHelper::defaultNameFilterDisables() const
+void QAndroidPlatformFileDialogHelper::exec()
{
- return false;
+ m_eventLoop.exec(QEventLoop::DialogExec);
}
}
diff --git a/src/plugins/platforms/android/qandroidplatformfiledialoghelper.h b/src/plugins/platforms/android/qandroidplatformfiledialoghelper.h
index 5cd26af7c9..fa9c3f47b3 100644
--- a/src/plugins/platforms/android/qandroidplatformfiledialoghelper.h
+++ b/src/plugins/platforms/android/qandroidplatformfiledialoghelper.h
@@ -44,6 +44,8 @@
#include <QEventLoop>
#include <qpa/qplatformdialoghelper.h>
#include <QtCore/private/qjnihelpers_p.h>
+#include <private/qjni_p.h>
+#include <QEventLoop>
QT_BEGIN_NAMESPACE
@@ -55,26 +57,34 @@ class QAndroidPlatformFileDialogHelper: public QPlatformFileDialogHelper, public
public:
QAndroidPlatformFileDialogHelper();
- void exec() override;
- bool show(Qt::WindowFlags windowFlags,
- Qt::WindowModality windowModality,
- QWindow *parent) override;
+ void exec() override;
+ bool show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent) override;
void hide() override;
- QString selectedNameFilter() const override;
- void selectNameFilter(const QString &filter) override;
- void setFilter() override;
- QList<QUrl> selectedFiles() const override;
- void selectFile(const QUrl &file) override;
- QUrl directory() const override;
- void setDirectory(const QUrl &directory) override;
- bool defaultNameFilterDisables() const override;
+ QString selectedNameFilter() const override { return QString(); };
+ void selectNameFilter(const QString &filter) override { Q_UNUSED(filter) };
+ void setFilter() override {};
+ QList<QUrl> selectedFiles() const override { return m_selectedFile; };
+ void selectFile(const QUrl &file) override { Q_UNUSED(file) };
+ QUrl directory() const override { return QUrl(); };
+ void setDirectory(const QUrl &directory) override { Q_UNUSED(directory) };
+ bool defaultNameFilterDisables() const override { return false; };
bool handleActivityResult(jint requestCode, jint resultCode, jobject data) override;
private:
+ QJNIObjectPrivate getFileDialogIntent(const QString &intentType);
+ void takePersistableUriPermission(const QJNIObjectPrivate &uri);
+ void setLocalFilesOnly(bool localOnly);
+ void setIntentTitle(const QString &title);
+ void setOpenableCategory();
+ void setAllowMultipleSelections(bool allowMultiple);
+ void setMimeTypes();
+
QEventLoop m_eventLoop;
- QUrl m_selectedFile;
+ QList<QUrl> m_selectedFile;
+ QJNIObjectPrivate m_intent;
+ const QJNIObjectPrivate m_activity;
};
}
diff --git a/src/plugins/platforms/android/qandroidplatformservices.cpp b/src/plugins/platforms/android/qandroidplatformservices.cpp
index 136637800b..c095613ce7 100644
--- a/src/plugins/platforms/android/qandroidplatformservices.cpp
+++ b/src/plugins/platforms/android/qandroidplatformservices.cpp
@@ -43,6 +43,7 @@
#include <QDebug>
#include <QMimeDatabase>
#include <QtCore/private/qjni_p.h>
+#include <private/qjnihelpers_p.h>
QT_BEGIN_NAMESPACE
@@ -57,20 +58,20 @@ bool QAndroidPlatformServices::openUrl(const QUrl &theUrl)
// if the file is local, we need to pass the MIME type, otherwise Android
// does not start an Intent to view this file
- if ((url.scheme().isEmpty() && QFile::exists(url.path())) || url.isLocalFile()) {
+ QLatin1String fileScheme("file");
+ if ((url.scheme().isEmpty() || url.scheme() == fileScheme) && QFile::exists(url.path())) {
// a real URL including the scheme is needed, else the Intent can not be started
- url.setScheme(QLatin1String("file"));
-
+ url.setScheme(fileScheme);
QMimeDatabase mimeDb;
mime = mimeDb.mimeTypeForUrl(url).name();
}
QJNIObjectPrivate urlString = QJNIObjectPrivate::fromString(url.toString());
QJNIObjectPrivate mimeString = QJNIObjectPrivate::fromString(mime);
- return QJNIObjectPrivate::callStaticMethod<jboolean>(QtAndroid::applicationClass(),
- "openURL",
- "(Ljava/lang/String;Ljava/lang/String;)Z",
- urlString.object(), mimeString.object());
+ return QJNIObjectPrivate::callStaticMethod<jboolean>(
+ QtAndroid::applicationClass(), "openURL",
+ "(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;)Z",
+ QtAndroidPrivate::context(), urlString.object(), mimeString.object());
}
bool QAndroidPlatformServices::openDocument(const QUrl &url)
diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.mm b/src/plugins/platforms/cocoa/qcocoabackingstore.mm
index 2e15d11564..cb019c3775 100644
--- a/src/plugins/platforms/cocoa/qcocoabackingstore.mm
+++ b/src/plugins/platforms/cocoa/qcocoabackingstore.mm
@@ -574,7 +574,8 @@ void QCALayerBackingStore::flush(QWindow *flushedWindow, const QRegion &region,
qCInfo(lcQpaBackingStore) << "Flushing" << subImage
<< "to" << flushedView.layer << "of subview" << flushedView;
- QCFType<CGImageRef> cgImage = subImage.toCGImage();
+ QCFType<CGImageRef> cgImage = CGImageCreateCopyWithColorSpace(
+ QCFType<CGImageRef>(subImage.toCGImage()), colorSpace());
flushedView.layer.contents = (__bridge id)static_cast<CGImageRef>(cgImage);
}
diff --git a/src/plugins/platforms/wasm/qwasmeventdispatcher.cpp b/src/plugins/platforms/wasm/qwasmeventdispatcher.cpp
index ca8db9b215..09acd37abc 100644
--- a/src/plugins/platforms/wasm/qwasmeventdispatcher.cpp
+++ b/src/plugins/platforms/wasm/qwasmeventdispatcher.cpp
@@ -194,6 +194,7 @@ void QWasmEventDispatcher::wakeUp()
{
#ifdef EMSCRIPTEN_HAS_ASYNC_RUN_IN_MAIN_RUNTIME_THREAD
if (!emscripten_is_main_runtime_thread())
+ if (m_hasMainLoop)
emscripten_async_run_in_main_runtime_thread_(EM_FUNC_SIG_VI, (void*)(&QWasmEventDispatcher::mainThreadWakeUp), this);
#endif
QEventDispatcherUNIX::wakeUp();
diff --git a/src/plugins/platforms/windows/.prev_CMakeLists.txt b/src/plugins/platforms/windows/.prev_CMakeLists.txt
index 299dda24af..92b2ccb217 100644
--- a/src/plugins/platforms/windows/.prev_CMakeLists.txt
+++ b/src/plugins/platforms/windows/.prev_CMakeLists.txt
@@ -95,6 +95,7 @@ qt_extend_target(QWindowsIntegrationPlugin CONDITION QT_FEATURE_accessibility
SOURCES
uiautomation/qwindowsuiaaccessibility.cpp uiautomation/qwindowsuiaaccessibility.h
uiautomation/qwindowsuiabaseprovider.cpp uiautomation/qwindowsuiabaseprovider.h
+ uiautomation/qwindowsuiaexpandcollapseprovider.cpp uiautomation/qwindowsuiaexpandcollapseprovider.h
uiautomation/qwindowsuiagriditemprovider.cpp uiautomation/qwindowsuiagriditemprovider.h
uiautomation/qwindowsuiagridprovider.cpp uiautomation/qwindowsuiagridprovider.h
uiautomation/qwindowsuiainvokeprovider.cpp uiautomation/qwindowsuiainvokeprovider.h
diff --git a/src/plugins/platforms/windows/CMakeLists.txt b/src/plugins/platforms/windows/CMakeLists.txt
index 81a8c3bfe9..4cb9608378 100644
--- a/src/plugins/platforms/windows/CMakeLists.txt
+++ b/src/plugins/platforms/windows/CMakeLists.txt
@@ -96,6 +96,7 @@ qt_extend_target(QWindowsIntegrationPlugin CONDITION QT_FEATURE_accessibility
SOURCES
uiautomation/qwindowsuiaaccessibility.cpp uiautomation/qwindowsuiaaccessibility.h
uiautomation/qwindowsuiabaseprovider.cpp uiautomation/qwindowsuiabaseprovider.h
+ uiautomation/qwindowsuiaexpandcollapseprovider.cpp uiautomation/qwindowsuiaexpandcollapseprovider.h
uiautomation/qwindowsuiagriditemprovider.cpp uiautomation/qwindowsuiagriditemprovider.h
uiautomation/qwindowsuiagridprovider.cpp uiautomation/qwindowsuiagridprovider.h
uiautomation/qwindowsuiainvokeprovider.cpp uiautomation/qwindowsuiainvokeprovider.h
diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.cpp b/src/plugins/platforms/windows/qwindowsinputcontext.cpp
index f1f5d3a96e..7c4ddbd2a1 100644
--- a/src/plugins/platforms/windows/qwindowsinputcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowsinputcontext.cpp
@@ -285,7 +285,7 @@ void QWindowsInputContext::showInputPanel()
// the Surface seems unnecessary there anyway. But leave it hidden for IME.
// Only trigger the native OSK if the Qt OSK is not in use.
static bool imModuleEmpty = qEnvironmentVariableIsEmpty("QT_IM_MODULE");
- bool nativeVKDisabled = QCoreApplication::testAttribute(Qt::AA_MSWindowsDisableVirtualKeyboard);
+ bool nativeVKDisabled = QCoreApplication::testAttribute(Qt::AA_DisableNativeVirtualKeyboard);
if ((imModuleEmpty && !nativeVKDisabled)
&& QOperatingSystemVersion::current()
>= QOperatingSystemVersion(QOperatingSystemVersion::Windows, 10, 0, 16299)) {
diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp
index 325956b7ba..7f47cd712f 100644
--- a/src/plugins/platforms/windows/qwindowstheme.cpp
+++ b/src/plugins/platforms/windows/qwindowstheme.cpp
@@ -248,8 +248,7 @@ enum DarkModeColors : QRgb {
darkModeBtnHighlightRgb = 0xc0c0c0,
darkModeBtnShadowRgb = 0x808080,
darkModeHighlightRgb = 0x0055ff, // deviating from 0x800080
- darkModeMenuHighlightRgb = darkModeHighlightRgb,
- darkModeGrayTextRgb = 0x00ff00
+ darkModeMenuHighlightRgb = darkModeHighlightRgb
};
// from QStyle::standardPalette
@@ -386,7 +385,7 @@ static inline QPalette menuPalette(const QPalette &systemPalette, bool light)
const QColor menuColor = light ? getSysColor(COLOR_MENU) : QColor(Qt::black);
const QColor menuTextColor = light ? getSysColor(COLOR_MENUTEXT) : QColor(Qt::white);
const QColor disabled = light
- ? getSysColor(COLOR_GRAYTEXT) : QColor(darkModeGrayTextRgb);
+ ? getSysColor(COLOR_GRAYTEXT) : QColor(darkModeBtnHighlightRgb);
// we might need a special color group for the result.
result.setColor(QPalette::Active, QPalette::Button, menuColor);
result.setColor(QPalette::Active, QPalette::Text, menuTextColor);
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index ee65b393d4..e635463951 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -2629,7 +2629,7 @@ static inline DWORD edgesToWinOrientation(Qt::Edges edges)
bool QWindowsWindow::startSystemResize(Qt::Edges edges)
{
- if (Q_UNLIKELY(!(window()->flags() & Qt::MSWindowsFixedSizeDialogHint)))
+ if (Q_UNLIKELY(window()->flags().testFlag(Qt::MSWindowsFixedSizeDialogHint)))
return false;
ReleaseCapture();
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiaexpandcollapseprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiaexpandcollapseprovider.cpp
new file mode 100644
index 0000000000..6ac8de23fa
--- /dev/null
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiaexpandcollapseprovider.cpp
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwindowsuiaexpandcollapseprovider.h"
+#include "qwindowsuiautils.h"
+#include "qwindowscontext.h"
+
+#include <QtGui/qaccessible.h>
+#include <QtCore/qloggingcategory.h>
+#include <QtCore/qstring.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QWindowsUiAutomation;
+
+
+QWindowsUiaExpandCollapseProvider::QWindowsUiaExpandCollapseProvider(QAccessible::Id id) :
+ QWindowsUiaBaseProvider(id)
+{
+}
+
+QWindowsUiaExpandCollapseProvider::~QWindowsUiaExpandCollapseProvider() = default;
+
+HRESULT STDMETHODCALLTYPE QWindowsUiaExpandCollapseProvider::Expand()
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ QAccessibleInterface *accessible = accessibleInterface();
+ if (!accessible)
+ return UIA_E_ELEMENTNOTAVAILABLE;
+
+ QAccessibleActionInterface *actionInterface = accessible->actionInterface();
+ if (!actionInterface)
+ return UIA_E_ELEMENTNOTAVAILABLE;
+
+ if (accessible->childCount() > 0 && accessible->child(0)->state().invisible)
+ actionInterface->doAction(QAccessibleActionInterface::showMenuAction());
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsUiaExpandCollapseProvider::Collapse()
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ QAccessibleInterface *accessible = accessibleInterface();
+ if (!accessible)
+ return UIA_E_ELEMENTNOTAVAILABLE;
+
+ QAccessibleActionInterface *actionInterface = accessible->actionInterface();
+ if (!actionInterface)
+ return UIA_E_ELEMENTNOTAVAILABLE;
+
+ if (accessible->childCount() > 0 && !accessible->child(0)->state().invisible)
+ actionInterface->doAction(QAccessibleActionInterface::showMenuAction());
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsUiaExpandCollapseProvider::get_ExpandCollapseState(__RPC__out ExpandCollapseState *pRetVal)
+{
+ qCDebug(lcQpaUiAutomation) << __FUNCTION__;
+
+ if (!pRetVal)
+ return E_INVALIDARG;
+ *pRetVal = ExpandCollapseState_LeafNode;
+
+ QAccessibleInterface *accessible = accessibleInterface();
+ if (!accessible)
+ return UIA_E_ELEMENTNOTAVAILABLE;
+
+ if (accessible->childCount() > 0)
+ *pRetVal = accessible->child(0)->state().invisible ?
+ ExpandCollapseState_Collapsed : ExpandCollapseState_Expanded;
+
+ return S_OK;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiaexpandcollapseprovider.h b/src/plugins/platforms/windows/uiautomation/qwindowsuiaexpandcollapseprovider.h
new file mode 100644
index 0000000000..f5b4c2e78b
--- /dev/null
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiaexpandcollapseprovider.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSUIAEXPANDCOLLAPSEPROVIDER_H
+#define QWINDOWSUIAEXPANDCOLLAPSEPROVIDER_H
+
+#include <QtGui/qtguiglobal.h>
+#if QT_CONFIG(accessibility)
+
+#include "qwindowsuiabaseprovider.h"
+
+QT_BEGIN_NAMESPACE
+
+// Implements the Expand/Collapse control pattern provider. Used for menu items with submenus.
+class QWindowsUiaExpandCollapseProvider : public QWindowsUiaBaseProvider,
+ public QWindowsComBase<IExpandCollapseProvider>
+{
+ Q_DISABLE_COPY_MOVE(QWindowsUiaExpandCollapseProvider)
+public:
+ explicit QWindowsUiaExpandCollapseProvider(QAccessible::Id id);
+ virtual ~QWindowsUiaExpandCollapseProvider() override;
+
+ // IExpandCollapseProvider
+ HRESULT STDMETHODCALLTYPE Expand() override;
+ HRESULT STDMETHODCALLTYPE Collapse() override;
+ HRESULT STDMETHODCALLTYPE get_ExpandCollapseState(__RPC__out ExpandCollapseState *pRetVal) override;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(accessibility)
+
+#endif // QWINDOWSUIAEXPANDCOLLAPSEPROVIDER_H
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp
index 5f564f81c2..9adc5c78dd 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp
@@ -53,6 +53,7 @@
#include "qwindowsuiagridprovider.h"
#include "qwindowsuiagriditemprovider.h"
#include "qwindowsuiawindowprovider.h"
+#include "qwindowsuiaexpandcollapseprovider.h"
#include "qwindowscombase.h"
#include "qwindowscontext.h"
#include "qwindowsuiautils.h"
@@ -341,6 +342,14 @@ HRESULT QWindowsUiaMainProvider::GetPatternProvider(PATTERNID idPattern, IUnknow
*pRetVal = new QWindowsUiaInvokeProvider(id());
}
break;
+ case UIA_ExpandCollapsePatternId:
+ // Menu items with submenus.
+ if (accessible->role() == QAccessible::MenuItem
+ && accessible->childCount() > 0
+ && accessible->child(0)->role() == QAccessible::PopupMenu) {
+ *pRetVal = new QWindowsUiaExpandCollapseProvider(id());
+ }
+ break;
default:
break;
}
@@ -396,7 +405,7 @@ HRESULT QWindowsUiaMainProvider::GetPropertyValue(PROPERTYID idProp, VARIANT *pR
// The native OSK should be disbled if the Qt OSK is in use,
// or if disabled via application attribute.
static bool imModuleEmpty = qEnvironmentVariableIsEmpty("QT_IM_MODULE");
- bool nativeVKDisabled = QCoreApplication::testAttribute(Qt::AA_MSWindowsDisableVirtualKeyboard);
+ bool nativeVKDisabled = QCoreApplication::testAttribute(Qt::AA_DisableNativeVirtualKeyboard);
// If we want to disable the native OSK auto-showing
// we have to report text fields as non-editable.
@@ -448,6 +457,10 @@ HRESULT QWindowsUiaMainProvider::GetPropertyValue(PROPERTYID idProp, VARIANT *pR
setVariantBool(wt == Qt::Popup || wt == Qt::ToolTip || wt == Qt::SplashScreen, pRetVal);
}
break;
+ case UIA_IsDialogPropertyId:
+ setVariantBool(accessible->role() == QAccessible::Dialog
+ || accessible->role() == QAccessible::AlertMessage, pRetVal);
+ break;
case UIA_FullDescriptionPropertyId:
setVariantString(accessible->text(QAccessible::Description), pRetVal);
break;
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp
index ab04384616..682b8c19c0 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp
@@ -161,7 +161,7 @@ long roleToControlTypeId(QAccessible::Role role)
{QAccessible::Sound, UIA_CustomControlTypeId},
{QAccessible::Cursor, UIA_CustomControlTypeId},
{QAccessible::Caret, UIA_CustomControlTypeId},
- {QAccessible::AlertMessage, UIA_CustomControlTypeId},
+ {QAccessible::AlertMessage, UIA_WindowControlTypeId},
{QAccessible::Window, UIA_WindowControlTypeId},
{QAccessible::Client, UIA_GroupControlTypeId},
{QAccessible::PopupMenu, UIA_MenuControlTypeId},
diff --git a/src/plugins/platforms/windows/uiautomation/uiautomation.pri b/src/plugins/platforms/windows/uiautomation/uiautomation.pri
index ee9332e7ea..1c4b018d1c 100644
--- a/src/plugins/platforms/windows/uiautomation/uiautomation.pri
+++ b/src/plugins/platforms/windows/uiautomation/uiautomation.pri
@@ -19,6 +19,7 @@ SOURCES += \
$$PWD/qwindowsuiagridprovider.cpp \
$$PWD/qwindowsuiagriditemprovider.cpp \
$$PWD/qwindowsuiawindowprovider.cpp \
+ $$PWD/qwindowsuiaexpandcollapseprovider.cpp \
$$PWD/qwindowsuiautils.cpp
HEADERS += \
@@ -39,6 +40,7 @@ HEADERS += \
$$PWD/qwindowsuiagridprovider.h \
$$PWD/qwindowsuiagriditemprovider.h \
$$PWD/qwindowsuiawindowprovider.h \
+ $$PWD/qwindowsuiaexpandcollapseprovider.h \
$$PWD/qwindowsuiautils.h
mingw: QMAKE_USE *= uuid
diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
index 4620f0fd1d..27a2526df1 100644
--- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
@@ -514,12 +514,10 @@ QXcbConnection::TouchDeviceData *QXcbConnection::populateTouchDevices(void *info
return isTouchDevice ? &m_touchDevices[deviceinfo->deviceid] : nullptr;
}
-#if QT_CONFIG(tabletevent)
static inline qreal fixed1616ToReal(xcb_input_fp1616_t val)
{
return qreal(val) / 0x10000;
}
-#endif // QT_CONFIG(tabletevent)
void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
{
diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp
index 698be45aa8..505f7343ce 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.cpp
+++ b/src/plugins/platforms/xcb/qxcbscreen.cpp
@@ -665,7 +665,9 @@ QImage::Format QXcbScreen::format() const
bool needsRgbSwap;
qt_xcb_imageFormatForVisual(connection(), screen()->root_depth, visualForId(screen()->root_visual), &format, &needsRgbSwap);
// We are ignoring needsRgbSwap here and just assumes the backing-store will handle it.
- return format;
+ if (format != QImage::Format_Invalid)
+ return format;
+ return QImage::Format_RGB32;
}
int QXcbScreen::forcedDpi() const
diff --git a/src/plugins/sqldrivers/mysql/qsql_mysql.cpp b/src/plugins/sqldrivers/mysql/qsql_mysql.cpp
index 2930df7261..41141e1dd4 100644
--- a/src/plugins/sqldrivers/mysql/qsql_mysql.cpp
+++ b/src/plugins/sqldrivers/mysql/qsql_mysql.cpp
@@ -78,17 +78,14 @@ class QMYSQLDriverPrivate : public QSqlDriverPrivate
Q_DECLARE_PUBLIC(QMYSQLDriver)
public:
- QMYSQLDriverPrivate() : QSqlDriverPrivate(), mysql(0),
+ QMYSQLDriverPrivate() : QSqlDriverPrivate(QSqlDriver::MySqlServer)
#if QT_CONFIG(textcodec)
- tc(QTextCodec::codecForLocale()),
-#else
- tc(0),
+ , tc(QTextCodec::codecForLocale())
#endif
- preparedQuerysEnabled(false) { dbmsType = QSqlDriver::MySqlServer; }
- MYSQL *mysql;
- QTextCodec *tc;
-
- bool preparedQuerysEnabled;
+ {}
+ MYSQL *mysql = nullptr;
+ QTextCodec *tc = nullptr;
+ bool preparedQuerysEnabled = false;
};
static inline QString toUnicode(QTextCodec *tc, const char *str)
@@ -201,46 +198,34 @@ class QMYSQLResultPrivate: public QSqlResultPrivate
public:
Q_DECLARE_SQLDRIVER_PRIVATE(QMYSQLDriver)
- QMYSQLResultPrivate(QMYSQLResult *q, const QMYSQLDriver *drv)
- : QSqlResultPrivate(q, drv),
- result(0),
- rowsAffected(0),
- hasBlobs(false)
- , stmt(0), meta(0), inBinds(0), outBinds(0)
- , preparedQuery(false)
- { }
-
- MYSQL_RES *result;
- MYSQL_ROW row;
-
- int rowsAffected;
+ using QSqlResultPrivate::QSqlResultPrivate;
bool bindInValues();
void bindBlobs();
- bool hasBlobs;
+ MYSQL_RES *result = nullptr;
+ MYSQL_ROW row;
+
struct QMyField
{
- QMyField()
- : outField(0), nullIndicator(false), bufLength(0ul),
- myField(0), type(QMetaType::UnknownType)
- {}
- char *outField;
- my_bool nullIndicator;
- ulong bufLength;
- MYSQL_FIELD *myField;
- QMetaType::Type type;
+ char *outField = nullptr;
+ MYSQL_FIELD *myField = nullptr;
+ QMetaType::Type type = QMetaType::UnknownType;
+ my_bool nullIndicator = false;
+ ulong bufLength = 0ul;
};
QVector<QMyField> fields;
- MYSQL_STMT* stmt;
- MYSQL_RES* meta;
+ MYSQL_STMT *stmt = nullptr;
+ MYSQL_RES *meta = nullptr;
- MYSQL_BIND *inBinds;
- MYSQL_BIND *outBinds;
+ MYSQL_BIND *inBinds = nullptr;
+ MYSQL_BIND *outBinds = nullptr;
- bool preparedQuery;
+ int rowsAffected = 0;
+ bool hasBlobs = false;
+ bool preparedQuery = false;
};
#if QT_CONFIG(textcodec)
diff --git a/src/plugins/sqldrivers/odbc/qsql_odbc.cpp b/src/plugins/sqldrivers/odbc/qsql_odbc.cpp
index 72b2133327..63e8f9f9fe 100644
--- a/src/plugins/sqldrivers/odbc/qsql_odbc.cpp
+++ b/src/plugins/sqldrivers/odbc/qsql_odbc.cpp
@@ -118,23 +118,19 @@ class QODBCDriverPrivate : public QSqlDriverPrivate
Q_DECLARE_PUBLIC(QODBCDriver)
public:
- enum DefaultCase{Lower, Mixed, Upper, Sensitive};
- QODBCDriverPrivate()
- : QSqlDriverPrivate(), hEnv(0), hDbc(0), unicode(false), useSchema(false), disconnectCount(0), datetime_precision(19),
- isFreeTDSDriver(false), hasSQLFetchScroll(true), hasMultiResultSets(false), isQuoteInitialized(false), quote(QLatin1Char('"'))
- {
- }
+ enum DefaultCase {Lower, Mixed, Upper, Sensitive};
+ using QSqlDriverPrivate::QSqlDriverPrivate;
- SQLHANDLE hEnv;
- SQLHANDLE hDbc;
+ SQLHANDLE hEnv = nullptr;
+ SQLHANDLE hDbc = nullptr;
- bool unicode;
- bool useSchema;
- int disconnectCount;
- int datetime_precision;
- bool isFreeTDSDriver;
- bool hasSQLFetchScroll;
- bool hasMultiResultSets;
+ int disconnectCount = 0;
+ int datetimePrecision = 19;
+ bool unicode = false;
+ bool useSchema = false;
+ bool isFreeTDSDriver = false;
+ bool hasSQLFetchScroll = true;
+ bool hasMultiResultSets = false;
bool checkDriver() const;
void checkUnicode();
@@ -150,8 +146,8 @@ public:
QString adjustCase(const QString&) const;
QChar quoteChar();
private:
- bool isQuoteInitialized;
- QChar quote;
+ bool isQuoteInitialized = false;
+ QChar quote = QLatin1Char('"');
};
class QODBCResultPrivate;
@@ -194,10 +190,7 @@ class QODBCResultPrivate: public QSqlResultPrivate
public:
Q_DECLARE_SQLDRIVER_PRIVATE(QODBCDriver)
QODBCResultPrivate(QODBCResult *q, const QODBCDriver *db)
- : QSqlResultPrivate(q, db),
- hStmt(0),
- useSchema(false),
- hasSQLFetchScroll(true)
+ : QSqlResultPrivate(q, db)
{
unicode = drv_d_func()->unicode;
useSchema = drv_d_func()->useSchema;
@@ -210,16 +203,15 @@ public:
SQLHANDLE dpEnv() const { return drv_d_func() ? drv_d_func()->hEnv : 0;}
SQLHANDLE dpDbc() const { return drv_d_func() ? drv_d_func()->hDbc : 0;}
- SQLHANDLE hStmt;
-
- bool unicode;
- bool useSchema;
+ SQLHANDLE hStmt = nullptr;
QSqlRecord rInf;
QVector<QVariant> fieldCache;
- int fieldCacheIdx;
- int disconnectCount;
- bool hasSQLFetchScroll;
+ int fieldCacheIdx = 0;
+ int disconnectCount = 0;
+ bool hasSQLFetchScroll = true;
+ bool unicode = false;
+ bool useSchema = false;
bool isStmtHandleValid() const;
void updateStmtHandleState();
@@ -1464,20 +1456,22 @@ bool QODBCResult::exec()
case QVariant::DateTime: {
QByteArray &ba = tmpStorage[i];
ba.resize(sizeof(TIMESTAMP_STRUCT));
- TIMESTAMP_STRUCT * dt = (TIMESTAMP_STRUCT *)const_cast<char *>(ba.constData());
- QDateTime qdt = val.toDateTime();
- dt->year = qdt.date().year();
- dt->month = qdt.date().month();
- dt->day = qdt.date().day();
- dt->hour = qdt.time().hour();
- dt->minute = qdt.time().minute();
- dt->second = qdt.time().second();
-
- int precision = d->drv_d_func()->datetime_precision - 20; // (20 includes a separating period)
+ TIMESTAMP_STRUCT *dt = reinterpret_cast<TIMESTAMP_STRUCT *>(const_cast<char *>(ba.constData()));
+ const QDateTime qdt = val.toDateTime();
+ const QDate qdate = qdt.date();
+ const QTime qtime = qdt.time();
+ dt->year = qdate.year();
+ dt->month = qdate.month();
+ dt->day = qdate.day();
+ dt->hour = qtime.hour();
+ dt->minute = qtime.minute();
+ dt->second = qtime.second();
+ // (20 includes a separating period)
+ const int precision = d->drv_d_func()->datetimePrecision - 20;
if (precision <= 0) {
dt->fraction = 0;
} else {
- dt->fraction = qdt.time().msec() * 1000000;
+ dt->fraction = qtime.msec() * 1000000;
// (How many leading digits do we want to keep? With SQL Server 2005, this should be 3: 123000000)
int keep = (int)qPow(10.0, 9 - qMin(9, precision));
@@ -1489,7 +1483,7 @@ bool QODBCResult::exec()
qParamType[bindValueType(i) & QSql::InOut],
SQL_C_TIMESTAMP,
SQL_TIMESTAMP,
- d->drv_d_func()->datetime_precision,
+ d->drv_d_func()->datetimePrecision,
precision,
(void *) dt,
0,
@@ -2245,7 +2239,7 @@ void QODBCDriverPrivate::checkDateTimePrecision()
if ( r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO )
{
if (SQLGetData(hStmt, 3, SQL_INTEGER, &columnSize, sizeof(columnSize), 0) == SQL_SUCCESS) {
- datetime_precision = (int)columnSize;
+ datetimePrecision = (int)columnSize;
}
}
}
diff --git a/src/plugins/sqldrivers/psql/qsql_psql.cpp b/src/plugins/sqldrivers/psql/qsql_psql.cpp
index 27841d9494..d2c57bcddc 100644
--- a/src/plugins/sqldrivers/psql/qsql_psql.cpp
+++ b/src/plugins/sqldrivers/psql/qsql_psql.cpp
@@ -149,26 +149,17 @@ class QPSQLDriverPrivate final : public QSqlDriverPrivate
{
Q_DECLARE_PUBLIC(QPSQLDriver)
public:
- QPSQLDriverPrivate() : QSqlDriverPrivate(),
- connection(nullptr),
- isUtf8(false),
- pro(QPSQLDriver::Version6),
- sn(nullptr),
- pendingNotifyCheck(false),
- hasBackslashEscape(false),
- stmtCount(0),
- currentStmtId(InvalidStatementId)
- { dbmsType = QSqlDriver::PostgreSQL; }
-
- PGconn *connection;
- bool isUtf8;
- QPSQLDriver::Protocol pro;
- QSocketNotifier *sn;
+ QPSQLDriverPrivate() : QSqlDriverPrivate(QSqlDriver::PostgreSQL) {}
+
QStringList seid;
- mutable bool pendingNotifyCheck;
- bool hasBackslashEscape;
- int stmtCount;
- StatementId currentStmtId;
+ PGconn *connection = nullptr;
+ QSocketNotifier *sn = nullptr;
+ QPSQLDriver::Protocol pro = QPSQLDriver::Version6;
+ StatementId currentStmtId = InvalidStatementId;
+ int stmtCount = 0;
+ mutable bool pendingNotifyCheck = false;
+ bool hasBackslashEscape = false;
+ bool isUtf8 = false;
void appendTables(QStringList &tl, QSqlQuery &t, QChar type);
PGresult *exec(const char *stmt);
@@ -297,25 +288,18 @@ class QPSQLResultPrivate : public QSqlResultPrivate
Q_DECLARE_PUBLIC(QPSQLResult)
public:
Q_DECLARE_SQLDRIVER_PRIVATE(QPSQLDriver)
- QPSQLResultPrivate(QPSQLResult *q, const QPSQLDriver *drv)
- : QSqlResultPrivate(q, drv),
- result(nullptr),
- stmtId(InvalidStatementId),
- currentSize(-1),
- canFetchMoreRows(false),
- preparedQueriesEnabled(false)
- { }
+ using QSqlResultPrivate::QSqlResultPrivate;
QString fieldSerial(int i) const override { return QLatin1Char('$') + QString::number(i + 1); }
void deallocatePreparedStmt();
- PGresult *result;
std::queue<PGresult*> nextResultSets;
QString preparedStmtId;
- StatementId stmtId;
- int currentSize;
- bool canFetchMoreRows;
- bool preparedQueriesEnabled;
+ PGresult *result = nullptr;
+ StatementId stmtId = InvalidStatementId;
+ int currentSize = -1;
+ bool canFetchMoreRows = false;
+ bool preparedQueriesEnabled = false;
bool processResults();
};
diff --git a/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp b/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp
index 009e8a39ef..27e7d02472 100644
--- a/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp
+++ b/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp
@@ -144,42 +144,33 @@ class QSQLiteDriverPrivate : public QSqlDriverPrivate
Q_DECLARE_PUBLIC(QSQLiteDriver)
public:
- inline QSQLiteDriverPrivate() : QSqlDriverPrivate(), access(0) { dbmsType = QSqlDriver::SQLite; }
- sqlite3 *access;
- QList <QSQLiteResult *> results;
+ inline QSQLiteDriverPrivate() : QSqlDriverPrivate(QSqlDriver::SQLite) {}
+ sqlite3 *access = nullptr;
+ QVector<QSQLiteResult *> results;
QStringList notificationid;
};
-class QSQLiteResultPrivate: public QSqlCachedResultPrivate
+class QSQLiteResultPrivate : public QSqlCachedResultPrivate
{
Q_DECLARE_PUBLIC(QSQLiteResult)
public:
Q_DECLARE_SQLDRIVER_PRIVATE(QSQLiteDriver)
- QSQLiteResultPrivate(QSQLiteResult *q, const QSQLiteDriver *drv);
+ using QSqlCachedResultPrivate::QSqlCachedResultPrivate;
void cleanup();
bool fetchNext(QSqlCachedResult::ValueCache &values, int idx, bool initialFetch);
// initializes the recordInfo and the cache
void initColumns(bool emptyResultset);
void finalize();
- sqlite3_stmt *stmt;
-
- bool skippedStatus; // the status of the fetchNext() that's skipped
- bool skipRow; // skip the next fetchNext()?
+ sqlite3_stmt *stmt = nullptr;
QSqlRecord rInf;
QVector<QVariant> firstRow;
+ bool skippedStatus = false; // the status of the fetchNext() that's skipped
+ bool skipRow = false; // skip the next fetchNext()?
};
-QSQLiteResultPrivate::QSQLiteResultPrivate(QSQLiteResult *q, const QSQLiteDriver *drv)
- : QSqlCachedResultPrivate(q, drv),
- stmt(0),
- skippedStatus(false),
- skipRow(false)
-{
-}
-
void QSQLiteResultPrivate::cleanup()
{
Q_Q(QSQLiteResult);
diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm
index 3cd04603e8..f473c3cbe3 100644
--- a/src/plugins/styles/mac/qmacstyle_mac.mm
+++ b/src/plugins/styles/mac/qmacstyle_mac.mm
@@ -3959,7 +3959,20 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
CGContextRotateCTM(ctx, M_PI_2);
}
+ // Now, if it's a trick with a popup button, it has an arrow
+ // which makes no sense on tabs.
+ NSPopUpArrowPosition oldPosition = NSPopUpArrowAtCenter;
+ NSPopUpButtonCell *pbCell = nil;
+ if (isPopupButton) {
+ pbCell = static_cast<NSPopUpButtonCell *>(pb.cell);
+ oldPosition = pbCell.arrowPosition;
+ pbCell.arrowPosition = NSPopUpNoArrow;
+ }
+
[pb.cell drawBezelWithFrame:r inView:pb.superview];
+
+ if (pbCell) // Restore, we may reuse it for a ComboBox.
+ pbCell.arrowPosition = oldPosition;
};
if (needsInactiveHack) {
diff --git a/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp b/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp
index e8d74180cd..30b3786a80 100644
--- a/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp
+++ b/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp
@@ -2217,7 +2217,7 @@ QRect QWindowsVistaStyle::subControlRect(ComplexControl control, const QStyleOpt
{
const int controlTop = int(6 * factor);
const int controlHeight = int(height - controlTop - 3 * factor);
- int iconExtent = proxy()->pixelMetric(PM_SmallIconSize);
+ int iconExtent = proxy()->pixelMetric(PM_SmallIconSize, option);
QSize iconSize = tb->icon.actualSize(QSize(iconExtent, iconExtent));
if (tb->icon.isNull())
iconSize = QSize(controlHeight, controlHeight);
diff --git a/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp b/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp
index 9d143da169..e43746e79f 100644
--- a/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp
+++ b/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp
@@ -3453,7 +3453,7 @@ QRect QWindowsXPStyle::subControlRect(ComplexControl cc, const QStyleOptionCompl
{
const int controlTop = 6;
const int controlHeight = height - controlTop - 3;
- const int iconExtent = proxy()->pixelMetric(PM_SmallIconSize);
+ const int iconExtent = proxy()->pixelMetric(PM_SmallIconSize, option);
QSize iconSize = tb->icon.actualSize(QSize(iconExtent, iconExtent));
if (tb->icon.isNull())
iconSize = QSize(controlHeight, controlHeight);
@@ -3575,7 +3575,7 @@ QSize QWindowsXPStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt
sz.rheight() += int(borderSize.bottom() + borderSize.top() - margin
+ qreal(1) / factor - 1);
}
- const int textMargins = 2*(proxy()->pixelMetric(PM_FocusFrameHMargin) + 1);
+ const int textMargins = 2*(proxy()->pixelMetric(PM_FocusFrameHMargin, option) + 1);
sz += QSize(qMax(pixelMetric(QStyle::PM_ScrollBarExtent, option, widget)
+ textMargins, 23), 0); //arrow button
}
diff --git a/src/sql/kernel/qsqldriver_p.h b/src/sql/kernel/qsqldriver_p.h
index 614fbf69a1..c2cdb25ac2 100644
--- a/src/sql/kernel/qsqldriver_p.h
+++ b/src/sql/kernel/qsqldriver_p.h
@@ -63,10 +63,10 @@ class QSqlDriverPrivate : public QObjectPrivate
Q_DECLARE_PUBLIC(QSqlDriver)
public:
- QSqlDriverPrivate(QSqlDriver::DbmsType dbmstype = QSqlDriver::UnknownDbms)
- : QObjectPrivate()
- , dbmsType(dbmstype)
- {}
+ QSqlDriverPrivate(QSqlDriver::DbmsType type = QSqlDriver::UnknownDbms)
+ : QObjectPrivate(),
+ dbmsType(type)
+ { }
QSqlError error;
QSql::NumericalPrecisionPolicy precisionPolicy = QSql::LowPrecisionDouble;
diff --git a/src/testlib/qtestlog.cpp b/src/testlib/qtestlog.cpp
index 7bd108ab00..a388780532 100644
--- a/src/testlib/qtestlog.cpp
+++ b/src/testlib/qtestlog.cpp
@@ -597,6 +597,6 @@ qint64 QTestLog::nsecsFunctionTime()
return elapsedFunctionTime.nsecsElapsed();
}
-#include "moc_qtestlog_p.cpp"
-
QT_END_NAMESPACE
+
+#include "moc_qtestlog_p.cpp"
diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp
index b4fe6a765e..078eea257d 100644
--- a/src/tools/moc/generator.cpp
+++ b/src/tools/moc/generator.cpp
@@ -377,7 +377,7 @@ void Generator::generateCode()
isConstructible ? index : 0);
int flags = 0;
- if (cdef->hasQGadget) {
+ if (cdef->hasQGadget || cdef->hasQNamespace) {
// Ideally, all the classes could have that flag. But this broke classes generated
// by qdbusxml2cpp which generate code that require that we call qt_metacall for properties
flags |= PropertyAccessInStaticMetaCall;
@@ -534,7 +534,7 @@ void Generator::generateCode()
if (isQObject)
fprintf(out, " nullptr,\n");
- else if (cdef->superclassList.size() && !cdef->hasQGadget) // for qobject, we know the super class must have a static metaobject
+ else if (cdef->superclassList.size() && !cdef->hasQGadget && !cdef->hasQNamespace) // for qobject, we know the super class must have a static metaobject
fprintf(out, " QMetaObject::SuperData::link<%s::staticMetaObject>(),\n", purestSuperClass.constData());
else if (cdef->superclassList.size()) // for gadgets we need to query at compile time for it
fprintf(out, " QtPrivate::MetaObjectForType<%s>::value(),\n", purestSuperClass.constData());
@@ -1181,7 +1181,7 @@ void Generator::generateStaticMetacall()
}
fprintf(out, ");\n");
fprintf(out, " if (_a[0]) *reinterpret_cast<%s**>(_a[0]) = _r; } break;\n",
- cdef->hasQGadget ? "void" : "QObject");
+ (cdef->hasQGadget || cdef->hasQNamespace) ? "void" : "QObject");
}
fprintf(out, " default: break;\n");
fprintf(out, " }\n");
diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp
index b37674320d..03976771e5 100644
--- a/src/tools/moc/moc.cpp
+++ b/src/tools/moc/moc.cpp
@@ -943,7 +943,7 @@ void Moc::parse()
ClassDef def;
static_cast<BaseDef &>(def) = static_cast<BaseDef>(n);
def.qualified += def.classname;
- def.hasQGadget = true;
+ def.hasQNamespace = true;
auto it = std::find_if(classList.begin(), classList.end(), [&def](const ClassDef &val) {
return def.classname == val.classname && def.qualified == val.qualified;
});
@@ -1867,8 +1867,12 @@ QJsonObject ClassDef::toJson() const
if (!props.isEmpty())
cls[QLatin1String("properties")] = props;
+ if (hasQObject)
+ cls[QLatin1String("object")] = true;
if (hasQGadget)
cls[QLatin1String("gadget")] = true;
+ if (hasQNamespace)
+ cls[QLatin1String("namespace")] = true;
QJsonArray superClasses;
diff --git a/src/tools/moc/moc.h b/src/tools/moc/moc.h
index 63caf36d61..743749433f 100644
--- a/src/tools/moc/moc.h
+++ b/src/tools/moc/moc.h
@@ -194,6 +194,7 @@ struct ClassDef : BaseDef {
bool hasQObject = false;
bool hasQGadget = false;
+ bool hasQNamespace = false;
QJsonObject toJson() const;
};
diff --git a/src/widgets/dialogs/qcolordialog.cpp b/src/widgets/dialogs/qcolordialog.cpp
index 689002b589..4247731275 100644
--- a/src/widgets/dialogs/qcolordialog.cpp
+++ b/src/widgets/dialogs/qcolordialog.cpp
@@ -346,7 +346,8 @@ void QWellArray::paintCell(QPainter* p, int row, int col, const QRect &rect)
const QPalette & g = palette();
QStyleOptionFrame opt;
- int dfw = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
+ opt.initFrom(this);
+ int dfw = style()->pixelMetric(QStyle::PM_DefaultFrameWidth, &opt);
opt.lineWidth = dfw;
opt.midLineWidth = 1;
opt.rect = rect.adjusted(b, b, -b, -b);
diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp
index 044401ac13..437ce4a114 100644
--- a/src/widgets/dialogs/qfiledialog.cpp
+++ b/src/widgets/dialogs/qfiledialog.cpp
@@ -2200,8 +2200,12 @@ QString QFileDialog::getOpenFileName(QWidget *parent,
Options options)
{
const QStringList schemes = QStringList(QStringLiteral("file"));
- const QUrl selectedUrl = getOpenFileUrl(parent, caption, QUrl::fromLocalFile(dir), filter, selectedFilter, options, schemes);
- return selectedUrl.toLocalFile();
+ const QUrl selectedUrl = getOpenFileUrl(parent, caption, QUrl::fromLocalFile(dir), filter,
+ selectedFilter, options, schemes);
+ if (selectedUrl.isLocalFile() || selectedUrl.isEmpty())
+ return selectedUrl.toLocalFile();
+ else
+ return selectedUrl.toString();
}
/*!
@@ -2310,11 +2314,16 @@ QStringList QFileDialog::getOpenFileNames(QWidget *parent,
Options options)
{
const QStringList schemes = QStringList(QStringLiteral("file"));
- const QList<QUrl> selectedUrls = getOpenFileUrls(parent, caption, QUrl::fromLocalFile(dir), filter, selectedFilter, options, schemes);
+ const QList<QUrl> selectedUrls = getOpenFileUrls(parent, caption, QUrl::fromLocalFile(dir),
+ filter, selectedFilter, options, schemes);
QStringList fileNames;
fileNames.reserve(selectedUrls.size());
- for (const QUrl &url : selectedUrls)
- fileNames << url.toLocalFile();
+ for (const QUrl &url : selectedUrls) {
+ if (url.isLocalFile() || url.isEmpty())
+ fileNames << url.toLocalFile();
+ else
+ fileNames << url.toString();
+ }
return fileNames;
}
@@ -2556,8 +2565,12 @@ QString QFileDialog::getSaveFileName(QWidget *parent,
Options options)
{
const QStringList schemes = QStringList(QStringLiteral("file"));
- const QUrl selectedUrl = getSaveFileUrl(parent, caption, QUrl::fromLocalFile(dir), filter, selectedFilter, options, schemes);
- return selectedUrl.toLocalFile();
+ const QUrl selectedUrl = getSaveFileUrl(parent, caption, QUrl::fromLocalFile(dir), filter,
+ selectedFilter, options, schemes);
+ if (selectedUrl.isLocalFile() || selectedUrl.isEmpty())
+ return selectedUrl.toLocalFile();
+ else
+ return selectedUrl.toString();
}
/*!
@@ -2664,8 +2677,12 @@ QString QFileDialog::getExistingDirectory(QWidget *parent,
Options options)
{
const QStringList schemes = QStringList(QStringLiteral("file"));
- const QUrl selectedUrl = getExistingDirectoryUrl(parent, caption, QUrl::fromLocalFile(dir), options, schemes);
- return selectedUrl.toLocalFile();
+ const QUrl selectedUrl =
+ getExistingDirectoryUrl(parent, caption, QUrl::fromLocalFile(dir), options, schemes);
+ if (selectedUrl.isLocalFile() || selectedUrl.isEmpty())
+ return selectedUrl.toLocalFile();
+ else
+ return selectedUrl.toString();
}
/*!
diff --git a/src/widgets/dialogs/qwizard.cpp b/src/widgets/dialogs/qwizard.cpp
index 87f6875c8c..31e32bb931 100644
--- a/src/widgets/dialogs/qwizard.cpp
+++ b/src/widgets/dialogs/qwizard.cpp
@@ -64,6 +64,7 @@
# include "qshortcut.h"
#endif
#include "qstyle.h"
+#include "qstyleoption.h"
#include "qvarlengtharray.h"
#if defined(Q_OS_MACX)
#include <QtCore/QMetaMethod>
@@ -897,7 +898,9 @@ QWizardLayoutInfo QWizardPrivate::layoutInfoForCurrentPage()
QWizardLayoutInfo info;
- const int layoutHorizontalSpacing = style->pixelMetric(QStyle::PM_LayoutHorizontalSpacing);
+ QStyleOption option;
+ option.initFrom(q);
+ const int layoutHorizontalSpacing = style->pixelMetric(QStyle::PM_LayoutHorizontalSpacing, &option);
info.topLevelMarginLeft = style->pixelMetric(QStyle::PM_LayoutLeftMargin, nullptr, q);
info.topLevelMarginRight = style->pixelMetric(QStyle::PM_LayoutRightMargin, nullptr, q);
info.topLevelMarginTop = style->pixelMetric(QStyle::PM_LayoutTopMargin, nullptr, q);
@@ -909,7 +912,7 @@ QWizardLayoutInfo QWizardPrivate::layoutInfoForCurrentPage()
info.hspacing = (layoutHorizontalSpacing == -1)
? style->layoutSpacing(QSizePolicy::DefaultType, QSizePolicy::DefaultType, Qt::Horizontal)
: layoutHorizontalSpacing;
- info.vspacing = style->pixelMetric(QStyle::PM_LayoutVerticalSpacing);
+ info.vspacing = style->pixelMetric(QStyle::PM_LayoutVerticalSpacing, &option);
info.buttonSpacing = (layoutHorizontalSpacing == -1)
? style->layoutSpacing(QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal)
: layoutHorizontalSpacing;
diff --git a/src/widgets/graphicsview/qgraphicslayout_p.h b/src/widgets/graphicsview/qgraphicslayout_p.h
index 0d91151e22..9e86ae2f76 100644
--- a/src/widgets/graphicsview/qgraphicslayout_p.h
+++ b/src/widgets/graphicsview/qgraphicslayout_p.h
@@ -87,8 +87,8 @@ public:
Q_ASSERT(style);
if (widget) //###
m_styleOption.initFrom(widget);
- m_defaultSpacing[0] = style->pixelMetric(QStyle::PM_LayoutHorizontalSpacing);
- m_defaultSpacing[1] = style->pixelMetric(QStyle::PM_LayoutVerticalSpacing);
+ m_defaultSpacing[0] = style->pixelMetric(QStyle::PM_LayoutHorizontalSpacing, &m_styleOption);
+ m_defaultSpacing[1] = style->pixelMetric(QStyle::PM_LayoutVerticalSpacing, &m_styleOption);
}
inline void invalidate() { m_valid = false; m_style = nullptr; m_widget = nullptr; }
diff --git a/src/widgets/graphicsview/qgraphicslayoutstyleinfo.cpp b/src/widgets/graphicsview/qgraphicslayoutstyleinfo.cpp
index 2f1526cc78..58b9f8bb9d 100644
--- a/src/widgets/graphicsview/qgraphicslayoutstyleinfo.cpp
+++ b/src/widgets/graphicsview/qgraphicslayoutstyleinfo.cpp
@@ -80,7 +80,9 @@ qreal QGraphicsLayoutStyleInfo::perItemSpacing(QLayoutPolicy::ControlType contro
qreal QGraphicsLayoutStyleInfo::spacing(Qt::Orientation orientation) const
{
Q_ASSERT(style());
- return style()->pixelMetric(orientation == Qt::Horizontal ? QStyle::PM_LayoutHorizontalSpacing : QStyle::PM_LayoutVerticalSpacing);
+ return style()->pixelMetric(orientation == Qt::Horizontal
+ ? QStyle::PM_LayoutHorizontalSpacing : QStyle::PM_LayoutVerticalSpacing,
+ &m_styleOption);
}
qreal QGraphicsLayoutStyleInfo::windowMargin(Qt::Orientation orientation) const
diff --git a/src/widgets/graphicsview/qgraphicsproxywidget.cpp b/src/widgets/graphicsview/qgraphicsproxywidget.cpp
index a9a57c57fa..fe3475e6bb 100644
--- a/src/widgets/graphicsview/qgraphicsproxywidget.cpp
+++ b/src/widgets/graphicsview/qgraphicsproxywidget.cpp
@@ -183,7 +183,9 @@ QT_BEGIN_NAMESPACE
\warning This class is provided for convenience when bridging
QWidgets and QGraphicsItems, it should not be used for
- high-performance scenarios.
+ high-performance scenarios. In particular, embedding widgets into a scene
+ that is then displayed through a QGraphicsView that uses an OpenGL viewport
+ will not work for all combinations.
\sa QGraphicsScene::addWidget(), QGraphicsWidget
*/
diff --git a/src/widgets/graphicsview/qgraphicsview.cpp b/src/widgets/graphicsview/qgraphicsview.cpp
index 686b41960a..a75f1ab24b 100644
--- a/src/widgets/graphicsview/qgraphicsview.cpp
+++ b/src/widgets/graphicsview/qgraphicsview.cpp
@@ -123,6 +123,10 @@ static const int QGRAPHICSVIEW_PREALLOC_STYLE_OPTIONS = 503; // largest prime <
\image graphicsview-view.png
+ \note Using an OpenGL viewport limits the ability to use QGraphicsProxyWidget.
+ Not all combinations of widgets and styles can be supported with such a setup.
+ You should carefully test your UI and make the necessary adjustments.
+
\sa QGraphicsScene, QGraphicsItem, QGraphicsSceneEvent
*/
@@ -782,6 +786,27 @@ void QGraphicsViewPrivate::updateRubberBand(const QMouseEvent *event)
if (scene)
scene->setSelectionArea(selectionArea, rubberBandSelectionOperation, rubberBandSelectionMode, q->viewportTransform());
}
+
+void QGraphicsViewPrivate::clearRubberBand()
+{
+ Q_Q(QGraphicsView);
+ if (dragMode != QGraphicsView::RubberBandDrag || !sceneInteractionAllowed || !rubberBanding)
+ return;
+
+ if (viewportUpdateMode != QGraphicsView::NoViewportUpdate) {
+ if (viewportUpdateMode != QGraphicsView::FullViewportUpdate)
+ q->viewport()->update(rubberBandRegion(q->viewport(), rubberBandRect));
+ else
+ updateAll();
+ }
+
+ rubberBanding = false;
+ rubberBandSelectionOperation = Qt::ReplaceSelection;
+ if (!rubberBandRect.isNull()) {
+ rubberBandRect = QRect();
+ emit q->rubberBandChanged(rubberBandRect, QPointF(), QPointF());
+ }
+}
#endif
/*!
@@ -1485,6 +1510,10 @@ void QGraphicsView::setDragMode(DragMode mode)
if (d->dragMode == mode)
return;
+#if QT_CONFIG(rubberband)
+ d->clearRubberBand();
+#endif
+
#ifndef QT_NO_CURSOR
if (d->dragMode == ScrollHandDrag)
viewport()->unsetCursor();
@@ -3354,20 +3383,7 @@ void QGraphicsView::mouseReleaseEvent(QMouseEvent *event)
#if QT_CONFIG(rubberband)
if (d->dragMode == QGraphicsView::RubberBandDrag && d->sceneInteractionAllowed && !event->buttons()) {
- if (d->rubberBanding) {
- if (d->viewportUpdateMode != QGraphicsView::NoViewportUpdate){
- if (d->viewportUpdateMode != FullViewportUpdate)
- viewport()->update(d->rubberBandRegion(viewport(), d->rubberBandRect));
- else
- d->updateAll();
- }
- d->rubberBanding = false;
- d->rubberBandSelectionOperation = Qt::ReplaceSelection;
- if (!d->rubberBandRect.isNull()) {
- d->rubberBandRect = QRect();
- emit rubberBandChanged(d->rubberBandRect, QPointF(), QPointF());
- }
- }
+ d->clearRubberBand();
} else
#endif
if (d->dragMode == QGraphicsView::ScrollHandDrag && event->button() == Qt::LeftButton) {
diff --git a/src/widgets/graphicsview/qgraphicsview_p.h b/src/widgets/graphicsview/qgraphicsview_p.h
index 01af61d6ba..e877e6e887 100644
--- a/src/widgets/graphicsview/qgraphicsview_p.h
+++ b/src/widgets/graphicsview/qgraphicsview_p.h
@@ -140,6 +140,7 @@ public:
QRect rubberBandRect;
QRegion rubberBandRegion(const QWidget *widget, const QRect &rect) const;
void updateRubberBand(const QMouseEvent *event);
+ void clearRubberBand();
bool rubberBanding;
Qt::ItemSelectionMode rubberBandSelectionMode;
Qt::ItemSelectionOperation rubberBandSelectionOperation;
diff --git a/src/widgets/graphicsview/qgraphicswidget.cpp b/src/widgets/graphicsview/qgraphicswidget.cpp
index 1035ed3575..6242314e1d 100644
--- a/src/widgets/graphicsview/qgraphicswidget.cpp
+++ b/src/widgets/graphicsview/qgraphicswidget.cpp
@@ -615,7 +615,7 @@ void QGraphicsWidget::unsetWindowFrameMargins()
QStyleOptionTitleBar bar;
d->initStyleOptionTitleBar(&bar);
QStyle *style = this->style();
- qreal margin = style->pixelMetric(QStyle::PM_MdiSubWindowFrameWidth);
+ const qreal margin = style->pixelMetric(QStyle::PM_MdiSubWindowFrameWidth, &bar);
qreal titleBarHeight = d->titleBarHeight(bar);
setWindowFrameMargins(margin, titleBarHeight, margin, margin);
} else {
diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp
index 2524d4acfa..ebef36d033 100644
--- a/src/widgets/itemviews/qabstractitemview.cpp
+++ b/src/widgets/itemviews/qabstractitemview.cpp
@@ -705,15 +705,6 @@ void QAbstractItemView::setModel(QAbstractItemModel *model)
}
d->model = (model ? model : QAbstractItemModelPrivate::staticEmptyModel());
- // These asserts do basic sanity checking of the model
- Q_ASSERT_X(d->model->index(0,0) == d->model->index(0,0),
- "QAbstractItemView::setModel",
- "A model should return the exact same index "
- "(including its internal id/pointer) when asked for it twice in a row.");
- Q_ASSERT_X(!d->model->index(0,0).parent().isValid(),
- "QAbstractItemView::setModel",
- "The parent of a top level index should be invalid");
-
if (d->model != QAbstractItemModelPrivate::staticEmptyModel()) {
connect(d->model, SIGNAL(destroyed()),
this, SLOT(_q_modelDestroyed()));
@@ -3244,8 +3235,10 @@ void QAbstractItemView::setIndexWidget(const QModelIndex &index, QWidget *widget
widget->installEventFilter(this);
widget->show();
dataChanged(index, index); // update the geometry
- if (!d->delayedPendingLayout)
+ if (!d->delayedPendingLayout) {
widget->setGeometry(visualRect(index));
+ d->doDelayedItemsLayout(); // relayout due to updated geometry
+ }
}
}
diff --git a/src/widgets/itemviews/qitemdelegate.cpp b/src/widgets/itemviews/qitemdelegate.cpp
index 4420d39b8e..40ad48c655 100644
--- a/src/widgets/itemviews/qitemdelegate.cpp
+++ b/src/widgets/itemviews/qitemdelegate.cpp
@@ -1122,7 +1122,7 @@ QRect QItemDelegate::textRectangle(QPainter * /*painter*/, const QRect &rect,
QSizeF fpSize = d->doTextLayout(rect.width());
const QSize size = QSize(qCeil(fpSize.width()), qCeil(fpSize.height()));
// ###: textRectangle should take style option as argument
- const int textMargin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1;
+ const int textMargin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin, nullptr) + 1;
return QRect(0, 0, size.width() + 2 * textMargin, size.height());
}
diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp
index ec01922746..4cb9214ff4 100644
--- a/src/widgets/itemviews/qlistview.cpp
+++ b/src/widgets/itemviews/qlistview.cpp
@@ -1728,8 +1728,11 @@ void QListViewPrivate::prepareItemsLayout()
layoutBounds = QRect(QPoint(), q->maximumViewportSize());
int frameAroundContents = 0;
- if (q->style()->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents))
- frameAroundContents = q->style()->pixelMetric(QStyle::PM_DefaultFrameWidth) * 2;
+ if (q->style()->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents)) {
+ QStyleOption option;
+ option.initFrom(q);
+ frameAroundContents = q->style()->pixelMetric(QStyle::PM_DefaultFrameWidth, &option) * 2;
+ }
// maximumViewportSize() already takes scrollbar into account if policy is
// Qt::ScrollBarAlwaysOn but scrollbar extent must be deduced if policy
diff --git a/src/widgets/itemviews/qtablewidget.cpp b/src/widgets/itemviews/qtablewidget.cpp
index 60abd02564..7b1f1a1caf 100644
--- a/src/widgets/itemviews/qtablewidget.cpp
+++ b/src/widgets/itemviews/qtablewidget.cpp
@@ -247,8 +247,8 @@ void QTableModel::removeItem(QTableWidgetItem *item)
{
int i = tableItems.indexOf(item);
if (i != -1) {
- tableItems[i] = 0;
QModelIndex idx = index(item);
+ tableItems[i] = nullptr;
emit dataChanged(idx, idx);
return;
}
diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp
index 129569a466..f49461b2d0 100644
--- a/src/widgets/kernel/qapplication.cpp
+++ b/src/widgets/kernel/qapplication.cpp
@@ -1904,9 +1904,12 @@ bool QApplication::event(QEvent *e)
}
if(e->type() == QEvent::LanguageChange) {
+ // QGuiApplication::event does not account for the cases where
+ // there is a top level widget without a window handle. So they
+ // need to have the event posted here
const QWidgetList list = topLevelWidgets();
for (auto *w : list) {
- if (!(w->windowType() == Qt::Desktop))
+ if (!w->windowHandle() && (w->windowType() != Qt::Desktop))
postEvent(w, new QEvent(QEvent::LanguageChange));
}
}
@@ -3299,7 +3302,7 @@ QT_WARNING_POP
bool eventAccepted = tablet->isAccepted();
while (w) {
QTabletEvent te(tablet->type(), relpos, tablet->globalPosF(),
- tablet->device(), tablet->pointerType(),
+ tablet->deviceType(), tablet->pointerType(),
tablet->pressure(), tablet->xTilt(), tablet->yTilt(),
tablet->tangentialPressure(), tablet->rotation(), tablet->z(),
tablet->modifiers(), tablet->uniqueId(), tablet->button(), tablet->buttons());
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index c5379941ef..b4699ae040 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -152,6 +152,7 @@ QWidgetPrivate::QWidgetPrivate(int version)
#endif
, directFontResolveMask(0)
, inheritedFontResolveMask(0)
+ , directPaletteResolveMask(0)
, inheritedPaletteResolveMask(0)
, leftmargin(0)
, topmargin(0)
@@ -1850,7 +1851,9 @@ void QWidgetPrivate::propagatePaletteChange()
if (q->isWindow() && !q->testAttribute(Qt::WA_WindowPropagation)) {
inheritedPaletteResolveMask = 0;
}
- QPalette::ResolveMask mask = data.pal.resolve() | inheritedPaletteResolveMask;
+
+ directPaletteResolveMask = data.pal.resolve();
+ auto mask = directPaletteResolveMask | inheritedPaletteResolveMask;
const bool useStyleSheetPropagationInWidgetStyles =
QCoreApplication::testAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles);
@@ -10454,6 +10457,12 @@ void QWidget::setParent(QWidget *parent, Qt::WindowFlags f)
if (!useStyleSheetPropagationInWidgetStyles && !testAttribute(Qt::WA_StyleSheet)
&& (!parent || !parent->testAttribute(Qt::WA_StyleSheet))) {
+ // if the parent has a font set or inherited, then propagate the mask to the new child
+ if (parent) {
+ const auto pd = parent->d_func();
+ d->inheritedFontResolveMask = pd->directFontResolveMask | pd->inheritedFontResolveMask;
+ d->inheritedPaletteResolveMask = pd->directPaletteResolveMask | pd->inheritedPaletteResolveMask;
+ }
d->resolveFont();
d->resolvePalette();
}
diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h
index 0d0077548c..3c29b48973 100644
--- a/src/widgets/kernel/qwidget_p.h
+++ b/src/widgets/kernel/qwidget_p.h
@@ -672,6 +672,7 @@ public:
// Other variables.
uint directFontResolveMask;
uint inheritedFontResolveMask;
+ decltype(std::declval<QPalette>().resolve()) directPaletteResolveMask;
QPalette::ResolveMask inheritedPaletteResolveMask;
short leftmargin;
short topmargin;
diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp
index 904067afda..4ba5469e9d 100644
--- a/src/widgets/kernel/qwidgetwindow.cpp
+++ b/src/widgets/kernel/qwidgetwindow.cpp
@@ -727,19 +727,6 @@ bool QWidgetWindow::updateSize()
return changed;
}
-bool QWidgetWindow::updatePos()
-{
- bool changed = false;
- if (m_widget->testAttribute(Qt::WA_OutsideWSRange))
- return changed;
- if (m_widget->data->crect.topLeft() != geometry().topLeft()) {
- changed = true;
- m_widget->data->crect.moveTopLeft(geometry().topLeft());
- }
- updateMargins();
- return changed;
-}
-
void QWidgetWindow::updateMargins()
{
const QMargins margins = frameMargins();
@@ -800,8 +787,28 @@ void QWidgetWindow::updateNormalGeometry()
void QWidgetWindow::handleMoveEvent(QMoveEvent *event)
{
- if (updatePos())
- QGuiApplication::forwardEvent(m_widget, event);
+ if (m_widget->testAttribute(Qt::WA_OutsideWSRange))
+ return;
+
+ auto oldPosition = m_widget->data->crect.topLeft();
+ auto newPosition = geometry().topLeft();
+
+ if (!m_widget->isTopLevel()) {
+ if (auto *nativeParent = m_widget->nativeParentWidget())
+ newPosition = m_widget->parentWidget()->mapFrom(nativeParent, newPosition);
+ }
+
+ bool changed = newPosition != oldPosition;
+
+ if (changed)
+ m_widget->data->crect.moveTopLeft(newPosition);
+
+ updateMargins(); // FIXME: Only do when changed?
+
+ if (changed) {
+ QMoveEvent widgetEvent(newPosition, oldPosition);
+ QGuiApplication::forwardEvent(m_widget, &widgetEvent, event);
+ }
}
void QWidgetWindow::handleResizeEvent(QResizeEvent *event)
diff --git a/src/widgets/kernel/qwidgetwindow_p.h b/src/widgets/kernel/qwidgetwindow_p.h
index 80a345465d..5689e129c3 100644
--- a/src/widgets/kernel/qwidgetwindow_p.h
+++ b/src/widgets/kernel/qwidgetwindow_p.h
@@ -125,7 +125,6 @@ private slots:
private:
void repaintWindow();
bool updateSize();
- bool updatePos();
void updateMargins();
void updateNormalGeometry();
diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp
index f4a53c9dfe..4b0094e578 100644
--- a/src/widgets/styles/qcommonstyle.cpp
+++ b/src/widgets/styles/qcommonstyle.cpp
@@ -431,7 +431,7 @@ void QCommonStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, Q
QIcon::Active, QIcon::Off);
}
- int size = proxy()->pixelMetric(QStyle::PM_SmallIconSize);
+ const int size = proxy()->pixelMetric(QStyle::PM_SmallIconSize, opt);
QIcon::Mode mode = opt->state & State_Enabled ?
(opt->state & State_Raised ? QIcon::Active : QIcon::Normal)
: QIcon::Disabled;
@@ -477,7 +477,7 @@ void QCommonStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, Q
if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
int lw = frame->lineWidth;
if (lw <= 0)
- lw = proxy()->pixelMetric(PM_DockWidgetFrameWidth);
+ lw = proxy()->pixelMetric(PM_DockWidgetFrameWidth, opt);
qDrawShadePanel(p, frame->rect, frame->palette, false, lw);
}
@@ -563,8 +563,8 @@ void QCommonStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, Q
int bsx = 0;
int bsy = 0;
if (opt->state & State_Sunken) {
- bsx = proxy()->pixelMetric(PM_ButtonShiftHorizontal);
- bsy = proxy()->pixelMetric(PM_ButtonShiftVertical);
+ bsx = proxy()->pixelMetric(PM_ButtonShiftHorizontal, opt);
+ bsy = proxy()->pixelMetric(PM_ButtonShiftVertical, opt);
}
p->save();
p->translate(sx + bsx, sy + bsy);
@@ -994,7 +994,7 @@ QSize QCommonStylePrivate::viewItemSize(const QStyleOptionViewItem *option, int
}
if (wrapText && option->features & QStyleOptionViewItem::HasCheckIndicator)
- bounds.setWidth(bounds.width() - proxyStyle->pixelMetric(QStyle::PM_IndicatorWidth) - 2 * textMargin);
+ bounds.setWidth(bounds.width() - proxyStyle->pixelMetric(QStyle::PM_IndicatorWidth, option) - 2 * textMargin);
const int lineWidth = bounds.width();
const QSizeF size = viewItemTextLayout(textLayout, lineWidth);
@@ -1240,7 +1240,7 @@ void QCommonStylePrivate::tabLayout(const QStyleOptionTab *opt, const QWidget *w
if (!opt->icon.isNull()) {
QSize iconSize = opt->iconSize;
if (!iconSize.isValid()) {
- int iconExtent = proxyStyle->pixelMetric(QStyle::PM_SmallIconSize);
+ int iconExtent = proxyStyle->pixelMetric(QStyle::PM_SmallIconSize, opt);
iconSize = QSize(iconExtent, iconExtent);
}
QSize tabIconSize = opt->icon.actualSize(iconSize,
@@ -1490,7 +1490,7 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt,
| Qt::TextSingleLine;
if (!proxy()->styleHint(SH_UnderlineShortcut, mbi, widget))
alignment |= Qt::TextHideMnemonic;
- int iconExtent = proxy()->pixelMetric(PM_SmallIconSize);
+ int iconExtent = proxy()->pixelMetric(PM_SmallIconSize, opt);
QPixmap pix = mbi->icon.pixmap(qt_getWindow(widget), QSize(iconExtent, iconExtent), (mbi->state & State_Enabled) ? QIcon::Normal : QIcon::Disabled);
if (!pix.isNull())
proxy()->drawItemPixmap(p,mbi->rect, alignment, pix);
@@ -1646,7 +1646,7 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt,
if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
QRect rect = header->rect;
if (!header->icon.isNull()) {
- int iconExtent = proxy()->pixelMetric(PM_SmallIconSize);
+ int iconExtent = proxy()->pixelMetric(PM_SmallIconSize, opt);
QPixmap pixmap
= header->icon.pixmap(qt_getWindow(widget), QSize(iconExtent, iconExtent), (header->state & State_Enabled) ? QIcon::Normal : QIcon::Disabled);
int pixw = pixmap.width() / pixmap.devicePixelRatio();
@@ -3863,8 +3863,8 @@ void QCommonStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCompl
if (opt->activeSubControls & QStyle::SC_MdiCloseButton && (opt->state & State_Sunken)) {
btnOpt.state |= State_Sunken;
btnOpt.state &= ~State_Raised;
- bsx = proxy()->pixelMetric(PM_ButtonShiftHorizontal);
- bsy = proxy()->pixelMetric(PM_ButtonShiftVertical);
+ bsx = proxy()->pixelMetric(PM_ButtonShiftHorizontal, opt);
+ bsy = proxy()->pixelMetric(PM_ButtonShiftVertical, opt);
} else {
btnOpt.state |= State_Raised;
btnOpt.state &= ~State_Sunken;
@@ -3880,8 +3880,8 @@ void QCommonStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCompl
if (opt->activeSubControls & QStyle::SC_MdiNormalButton && (opt->state & State_Sunken)) {
btnOpt.state |= State_Sunken;
btnOpt.state &= ~State_Raised;
- bsx = proxy()->pixelMetric(PM_ButtonShiftHorizontal);
- bsy = proxy()->pixelMetric(PM_ButtonShiftVertical);
+ bsx = proxy()->pixelMetric(PM_ButtonShiftHorizontal, opt);
+ bsy = proxy()->pixelMetric(PM_ButtonShiftVertical, opt);
} else {
btnOpt.state |= State_Raised;
btnOpt.state &= ~State_Sunken;
@@ -3897,8 +3897,8 @@ void QCommonStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCompl
if (opt->activeSubControls & QStyle::SC_MdiMinButton && (opt->state & State_Sunken)) {
btnOpt.state |= State_Sunken;
btnOpt.state &= ~State_Raised;
- bsx = proxy()->pixelMetric(PM_ButtonShiftHorizontal);
- bsy = proxy()->pixelMetric(PM_ButtonShiftVertical);
+ bsx = proxy()->pixelMetric(PM_ButtonShiftHorizontal, opt);
+ bsy = proxy()->pixelMetric(PM_ButtonShiftVertical, opt);
} else {
btnOpt.state |= State_Raised;
btnOpt.state &= ~State_Sunken;
@@ -4781,12 +4781,12 @@ int QCommonStyle::pixelMetric(PixelMetric m, const QStyleOption *opt, const QWid
} else if (widget) {
isWindow = widget->isWindow();
}
- ret = proxy()->pixelMetric(isWindow ? PM_DefaultTopLevelMargin : PM_DefaultChildMargin);
+ ret = proxy()->pixelMetric(isWindow ? PM_DefaultTopLevelMargin : PM_DefaultChildMargin, opt);
}
break;
case PM_LayoutHorizontalSpacing:
case PM_LayoutVerticalSpacing:
- ret = proxy()->pixelMetric(PM_DefaultLayoutSpacing);
+ ret = proxy()->pixelMetric(PM_DefaultLayoutSpacing, opt);
break;
case PM_DefaultTopLevelMargin:
@@ -4937,7 +4937,7 @@ QSize QCommonStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt,
} else {
h = mi->fontMetrics.height() + 8;
if (!mi->icon.isNull()) {
- int iconExtent = proxy()->pixelMetric(PM_SmallIconSize);
+ int iconExtent = proxy()->pixelMetric(PM_SmallIconSize, opt);
h = qMax(h, mi->icon.actualSize(QSize(iconExtent, iconExtent)).height() + 4);
}
}
@@ -4963,7 +4963,7 @@ QSize QCommonStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt,
case CT_ComboBox:
if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
int fw = cmb->frame ? proxy()->pixelMetric(PM_ComboBoxFrameWidth, opt, widget) * 2 : 0;
- const int textMargins = 2*(proxy()->pixelMetric(PM_FocusFrameHMargin) + 1);
+ const int textMargins = 2*(proxy()->pixelMetric(PM_FocusFrameHMargin, opt) + 1);
// QItemDelegate::sizeHint expands the textMargins two times, thus the 2*textMargins...
int other = qMax(23, 2*textMargins + proxy()->pixelMetric(QStyle::PM_ScrollBarExtent, opt, widget));
sz = QSize(sz.width() + fw + other, sz.height() + fw);
@@ -5214,8 +5214,8 @@ int QCommonStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget
if (widget) {
if(QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask*>(hret)) {
mask->region = widget->rect();
- int vmargin = proxy()->pixelMetric(QStyle::PM_FocusFrameVMargin),
- hmargin = proxy()->pixelMetric(QStyle::PM_FocusFrameHMargin);
+ const int vmargin = proxy()->pixelMetric(QStyle::PM_FocusFrameVMargin, opt);
+ const int hmargin = proxy()->pixelMetric(QStyle::PM_FocusFrameHMargin, opt);
mask->region -= QRect(widget->rect().adjusted(hmargin, vmargin, -hmargin, -vmargin));
}
}
@@ -5228,7 +5228,7 @@ int QCommonStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget
ret = true;
if(QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask*>(hret)) {
mask->region = opt->rect;
- int margin = proxy()->pixelMetric(PM_DefaultFrameWidth) * 2;
+ const int margin = proxy()->pixelMetric(PM_DefaultFrameWidth, opt) * 2;
mask->region -= opt->rect.adjusted(margin, margin, -margin, -margin);
}
}
diff --git a/src/widgets/styles/qfusionstyle.cpp b/src/widgets/styles/qfusionstyle.cpp
index 2b59e5736b..4427d69944 100644
--- a/src/widgets/styles/qfusionstyle.cpp
+++ b/src/widgets/styles/qfusionstyle.cpp
@@ -3349,8 +3349,8 @@ QRect QFusionStyle::subControlRect(ComplexControl control, const QStyleOptionCom
switch (subControl) {
case SC_SliderHandle: {
if (slider->orientation == Qt::Horizontal) {
- rect.setHeight(proxy()->pixelMetric(PM_SliderThickness));
- rect.setWidth(proxy()->pixelMetric(PM_SliderLength));
+ rect.setHeight(proxy()->pixelMetric(PM_SliderThickness, option));
+ rect.setWidth(proxy()->pixelMetric(PM_SliderLength, option));
int centerY = slider->rect.center().y() - rect.height() / 2;
if (slider->tickPosition & QSlider::TicksAbove)
centerY += tickSize;
@@ -3358,8 +3358,8 @@ QRect QFusionStyle::subControlRect(ComplexControl control, const QStyleOptionCom
centerY -= tickSize;
rect.moveTop(centerY);
} else {
- rect.setWidth(proxy()->pixelMetric(PM_SliderThickness));
- rect.setHeight(proxy()->pixelMetric(PM_SliderLength));
+ rect.setWidth(proxy()->pixelMetric(PM_SliderThickness, option));
+ rect.setHeight(proxy()->pixelMetric(PM_SliderLength, option));
int centerX = slider->rect.center().x() - rect.width() / 2;
if (slider->tickPosition & QSlider::TicksAbove)
centerX += tickSize;
diff --git a/src/widgets/styles/qpixmapstyle.cpp b/src/widgets/styles/qpixmapstyle.cpp
index 05e8467528..7cc32b2039 100644
--- a/src/widgets/styles/qpixmapstyle.cpp
+++ b/src/widgets/styles/qpixmapstyle.cpp
@@ -1003,13 +1003,13 @@ QSize QPixmapStyle::pushButtonSizeFromContents(const QStyleOption *option,
return d->computeSize(desc, w, h);
}
-QSize QPixmapStyle::lineEditSizeFromContents(const QStyleOption *,
+QSize QPixmapStyle::lineEditSizeFromContents(const QStyleOption *option,
const QSize &contentsSize, const QWidget *) const
{
Q_D(const QPixmapStyle);
const QPixmapStyleDescriptor &desc = d->descriptors.value(LE_Enabled);
- const int border = 2 * proxy()->pixelMetric(PM_DefaultFrameWidth);
+ const int border = 2 * proxy()->pixelMetric(PM_DefaultFrameWidth, option);
int w = contentsSize.width() + border + desc.margins.left() + desc.margins.right();
int h = contentsSize.height() + border + desc.margins.top() + desc.margins.bottom();
diff --git a/src/widgets/styles/qstyle.cpp b/src/widgets/styles/qstyle.cpp
index 4ac0a11a36..69167a1fe2 100644
--- a/src/widgets/styles/qstyle.cpp
+++ b/src/widgets/styles/qstyle.cpp
@@ -1074,7 +1074,7 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment,
\value SE_TreeViewDisclosureItem Area for the actual disclosure item in a tree branch.
- \value SE_DialogButtonBoxLayoutItem Area that counts for the parent layout.
+ \omitvalue SE_DialogButtonBoxLayoutItem
\value SE_GroupBoxLayoutItem Area that counts for the parent layout.
diff --git a/src/widgets/styles/qstyle.h b/src/widgets/styles/qstyle.h
index f37604e0fa..5844251ae5 100644
--- a/src/widgets/styles/qstyle.h
+++ b/src/widgets/styles/qstyle.h
@@ -185,7 +185,7 @@ public:
PE_IndicatorItemViewItemDrop,
PE_PanelItemViewItem,
- PE_PanelItemViewRow, // ### Qt 6: remove
+ PE_PanelItemViewRow,
PE_PanelStatusBar,
@@ -326,8 +326,10 @@ public:
SE_CheckBoxLayoutItem,
SE_ComboBoxLayoutItem,
SE_DateTimeEditLayoutItem,
- SE_DialogButtonBoxLayoutItem, // ### Qt 6: remove
- SE_LabelLayoutItem,
+#if QT_DEPRECATED_SINCE(5, 15) // ### Qt 6: remove
+ SE_DialogButtonBoxLayoutItem Q_DECL_ENUMERATOR_DEPRECATED,
+#endif
+ SE_LabelLayoutItem = SE_DateTimeEditLayoutItem + 2,
SE_ProgressBarLayoutItem,
SE_PushButtonLayoutItem,
SE_RadioButtonLayoutItem,
@@ -529,11 +531,13 @@ public:
PM_SpinBoxSliderHeight,
- PM_DefaultTopLevelMargin, // ### Qt 6: remove
- PM_DefaultChildMargin, // ### Qt 6: remove
- PM_DefaultLayoutSpacing, // ### Qt 6: remove
+#if QT_DEPRECATED_SINCE(5, 15) // ### Qt 6: remove
+ PM_DefaultTopLevelMargin Q_DECL_ENUMERATOR_DEPRECATED,
+ PM_DefaultChildMargin Q_DECL_ENUMERATOR_DEPRECATED,
+ PM_DefaultLayoutSpacing Q_DECL_ENUMERATOR_DEPRECATED,
+#endif
- PM_ToolBarIconSize,
+ PM_ToolBarIconSize = PM_SpinBoxSliderHeight + 4,
PM_ListViewIconSize,
PM_IconViewIconSize,
PM_SmallIconSize,
diff --git a/src/widgets/styles/qstylehelper.cpp b/src/widgets/styles/qstylehelper.cpp
index 61a59b03c1..ea65227fd5 100644
--- a/src/widgets/styles/qstylehelper.cpp
+++ b/src/widgets/styles/qstylehelper.cpp
@@ -101,7 +101,13 @@ Q_WIDGETS_EXPORT qreal dpi(const QStyleOption *option)
if (option)
return option->fontMetrics.fontDpi();
+ // Fall back to historical Qt behavior: hardocded 72 DPI on mac,
+ // primary screen DPI on other platforms.
+#ifdef Q_OS_DARWIN
return qstyleBaseDpi;
+#else
+ return qt_defaultDpiX();
+#endif
}
Q_WIDGETS_EXPORT qreal dpiScaled(qreal value, qreal dpi)
diff --git a/src/widgets/styles/qwindowsstyle.cpp b/src/widgets/styles/qwindowsstyle.cpp
index 8eb24d7557..4965d146b0 100644
--- a/src/widgets/styles/qwindowsstyle.cpp
+++ b/src/widgets/styles/qwindowsstyle.cpp
@@ -548,6 +548,8 @@ int QWindowsStyle::styleHint(StyleHint hint, const QStyleOption *opt, const QWid
switch (hint) {
case SH_EtchDisabledText:
+ ret = d_func()->isDarkMode() ? 0 : 1;
+ break;
case SH_Slider_SnapToValue:
case SH_PrintDialog_RightAlignButtons:
case SH_FontDialog_SelectAssociatedText:
diff --git a/src/widgets/widgets/qcalendarwidget.cpp b/src/widgets/widgets/qcalendarwidget.cpp
index fe1133c6c7..570ec72377 100644
--- a/src/widgets/widgets/qcalendarwidget.cpp
+++ b/src/widgets/widgets/qcalendarwidget.cpp
@@ -2232,7 +2232,9 @@ QSize QCalendarWidget::minimumSizeHint() const
int rows = 7;
int cols = 8;
- const int marginH = (style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1) * 2;
+ QStyleOption option;
+ option.initFrom(this);
+ const int marginH = (style()->pixelMetric(QStyle::PM_FocusFrameHMargin, &option) + 1) * 2;
if (horizontalHeaderFormat() == QCalendarWidget::NoHorizontalHeader) {
rows = 6;
diff --git a/src/widgets/widgets/qcombobox_p.h b/src/widgets/widgets/qcombobox_p.h
index 3e78e756a6..d7b2457c49 100644
--- a/src/widgets/widgets/qcombobox_p.h
+++ b/src/widgets/widgets/qcombobox_p.h
@@ -142,7 +142,7 @@ public:
setAttribute(Qt::WA_NoMousePropagation);
}
QSize sizeHint() const override {
- return QSize(20, style()->pixelMetric(QStyle::PM_MenuScrollerHeight));
+ return QSize(20, style()->pixelMetric(QStyle::PM_MenuScrollerHeight, nullptr, this));
}
protected:
diff --git a/src/widgets/widgets/qcommandlinkbutton.cpp b/src/widgets/widgets/qcommandlinkbutton.cpp
index 2b9258fd91..e9462ed229 100644
--- a/src/widgets/widgets/qcommandlinkbutton.cpp
+++ b/src/widgets/widgets/qcommandlinkbutton.cpp
@@ -208,7 +208,7 @@ bool QCommandLinkButtonPrivate::usingVistaStyle() const
//### This is a hack to detect if we are indeed running Vista style themed and not in classic
// When we add api to query for this, we should change this implementation to use it.
return q->style()->inherits("QWindowsVistaStyle")
- && !q->style()->pixelMetric(QStyle::PM_ButtonShiftHorizontal);
+ && q->style()->pixelMetric(QStyle::PM_ButtonShiftHorizontal, nullptr) == 0;
}
void QCommandLinkButtonPrivate::init()
@@ -355,8 +355,10 @@ void QCommandLinkButton::paintEvent(QPaintEvent *)
option.icon = QIcon(); //we draw this ourselves
QSize pixmapSize = icon().actualSize(iconSize());
- int vOffset = isDown() ? style()->pixelMetric(QStyle::PM_ButtonShiftVertical) : 0;
- int hOffset = isDown() ? style()->pixelMetric(QStyle::PM_ButtonShiftHorizontal) : 0;
+ const int vOffset = isDown()
+ ? style()->pixelMetric(QStyle::PM_ButtonShiftVertical, &option) : 0;
+ const int hOffset = isDown()
+ ? style()->pixelMetric(QStyle::PM_ButtonShiftHorizontal, &option) : 0;
//Draw icon
p.drawControl(QStyle::CE_PushButton, option);
diff --git a/src/widgets/widgets/qeffects.cpp b/src/widgets/widgets/qeffects.cpp
index 5cb8bb3c50..1f2d3517e8 100644
--- a/src/widgets/widgets/qeffects.cpp
+++ b/src/widgets/widgets/qeffects.cpp
@@ -54,6 +54,15 @@
QT_BEGIN_NAMESPACE
+static QWidget *effectParent(const QWidget* w)
+{
+ const int screenNumber = w ? QGuiApplication::screens().indexOf(w->screen()) : 0;
+ QT_WARNING_PUSH // ### Qt 6: Find a replacement for QDesktopWidget::screen()
+ QT_WARNING_DISABLE_DEPRECATED
+ return QApplication::desktop()->screen(screenNumber);
+ QT_WARNING_POP
+}
+
/*
Internal class QAlphaWidget.
@@ -98,12 +107,9 @@ static QAlphaWidget* q_blend = nullptr;
/*
Constructs a QAlphaWidget.
*/
-QT_WARNING_PUSH
-QT_WARNING_DISABLE_DEPRECATED // ### Qt 6: Find a replacement for QDesktopWidget::screen()
QAlphaWidget::QAlphaWidget(QWidget* w, Qt::WindowFlags f)
- : QWidget(QApplication::desktop()->screen(QDesktopWidgetPrivate::screenNumber(w)), f)
+ : QWidget(effectParent(w), f)
{
-QT_WARNING_POP
#ifndef Q_OS_WIN
setEnabled(false);
#endif
@@ -383,7 +389,7 @@ static QRollEffect* q_roll = nullptr;
Construct a QRollEffect widget.
*/
QRollEffect::QRollEffect(QWidget* w, Qt::WindowFlags f, DirFlags orient)
- : QWidget(nullptr, f), orientation(orient)
+ : QWidget(effectParent(w), f), orientation(orient)
{
#ifndef Q_OS_WIN
setEnabled(false);
diff --git a/src/widgets/widgets/qfocusframe.cpp b/src/widgets/widgets/qfocusframe.cpp
index 4d64c24db3..4e793d7a29 100644
--- a/src/widgets/widgets/qfocusframe.cpp
+++ b/src/widgets/widgets/qfocusframe.cpp
@@ -86,8 +86,10 @@ void QFocusFramePrivate::updateSize()
if (!widget)
return;
- int vmargin = q->style()->pixelMetric(QStyle::PM_FocusFrameVMargin),
- hmargin = q->style()->pixelMetric(QStyle::PM_FocusFrameHMargin);
+ QStyleOption opt;
+ q->initStyleOption(&opt);
+ int vmargin = q->style()->pixelMetric(QStyle::PM_FocusFrameVMargin, &opt),
+ hmargin = q->style()->pixelMetric(QStyle::PM_FocusFrameHMargin, &opt);
QPoint pos(widget->x(), widget->y());
if (q->parentWidget() != widget->parentWidget())
pos = widget->parentWidget()->mapTo(q->parentWidget(), pos);
@@ -98,8 +100,6 @@ void QFocusFramePrivate::updateSize()
q->setGeometry(geom);
QStyleHintReturnMask mask;
- QStyleOption opt;
- q->initStyleOption(&opt);
if (q->style()->styleHint(QStyle::SH_FocusFrame_Mask, &opt, q, &mask))
q->setMask(mask.region);
}
@@ -263,8 +263,8 @@ QFocusFrame::paintEvent(QPaintEvent *)
QStylePainter p(this);
QStyleOption option;
initStyleOption(&option);
- int vmargin = style()->pixelMetric(QStyle::PM_FocusFrameVMargin);
- int hmargin = style()->pixelMetric(QStyle::PM_FocusFrameHMargin);
+ const int vmargin = style()->pixelMetric(QStyle::PM_FocusFrameVMargin, &option);
+ const int hmargin = style()->pixelMetric(QStyle::PM_FocusFrameHMargin, &option);
QWidgetPrivate *wd = qt_widget_private(d->widget);
QRect rect = wd->clipRect().adjusted(0, 0, hmargin*2, vmargin*2);
p.setClipRect(rect);
diff --git a/src/widgets/widgets/qgroupbox.cpp b/src/widgets/widgets/qgroupbox.cpp
index 048fe42948..02a0bed325 100644
--- a/src/widgets/widgets/qgroupbox.cpp
+++ b/src/widgets/widgets/qgroupbox.cpp
@@ -491,9 +491,9 @@ QSize QGroupBox::minimumSizeHint() const
int baseWidth = metrics.horizontalAdvance(d->title) + metrics.horizontalAdvance(QLatin1Char(' '));
int baseHeight = metrics.height();
if (d->checkable) {
- baseWidth += style()->pixelMetric(QStyle::PM_IndicatorWidth);
- baseWidth += style()->pixelMetric(QStyle::PM_CheckBoxLabelSpacing);
- baseHeight = qMax(baseHeight, style()->pixelMetric(QStyle::PM_IndicatorHeight));
+ baseWidth += style()->pixelMetric(QStyle::PM_IndicatorWidth, &option);
+ baseWidth += style()->pixelMetric(QStyle::PM_CheckBoxLabelSpacing, &option);
+ baseHeight = qMax(baseHeight, style()->pixelMetric(QStyle::PM_IndicatorHeight, &option));
}
QSize size = style()->sizeFromContents(QStyle::CT_GroupBox, &option, QSize(baseWidth, baseHeight), this);
diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp
index bd5e0b047e..9faf161cb1 100644
--- a/src/widgets/widgets/qlineedit.cpp
+++ b/src/widgets/widgets/qlineedit.cpp
@@ -2075,7 +2075,7 @@ void QLineEdit::paintEvent(QPaintEvent *)
if (d->cursorVisible && !d->control->isReadOnly())
flags |= QWidgetLineControl::DrawCursor;
- d->control->setCursorWidth(style()->pixelMetric(QStyle::PM_TextCursorWidth));
+ d->control->setCursorWidth(style()->pixelMetric(QStyle::PM_TextCursorWidth, &panel));
d->control->draw(&p, topLeft, r, flags);
}
diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp
index daa50aa8ee..cae776159d 100644
--- a/src/widgets/widgets/qmenu.cpp
+++ b/src/widgets/widgets/qmenu.cpp
@@ -2851,7 +2851,7 @@ void QMenu::paintEvent(QPaintEvent *e)
frame.rect = rect();
frame.palette = palette();
frame.state = QStyle::State_None;
- frame.lineWidth = style()->pixelMetric(QStyle::PM_MenuPanelWidth);
+ frame.lineWidth = style()->pixelMetric(QStyle::PM_MenuPanelWidth, &frame);
frame.midLineWidth = 0;
style()->drawPrimitive(QStyle::PE_FrameMenu, &frame, &p, this);
}
diff --git a/src/widgets/widgets/qmenubar.cpp b/src/widgets/widgets/qmenubar.cpp
index 59c8af30b4..c8124468df 100644
--- a/src/widgets/widgets/qmenubar.cpp
+++ b/src/widgets/widgets/qmenubar.cpp
@@ -1014,7 +1014,7 @@ void QMenuBar::paintEvent(QPaintEvent *e)
frame.rect = rect();
frame.palette = palette();
frame.state = QStyle::State_None;
- frame.lineWidth = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth);
+ frame.lineWidth = style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, &frame);
frame.midLineWidth = 0;
style()->drawPrimitive(QStyle::PE_PanelMenuBar, &frame, &p, this);
}
diff --git a/src/widgets/widgets/qtoolbarextension.cpp b/src/widgets/widgets/qtoolbarextension.cpp
index bbe7eddaa4..165c7f274b 100644
--- a/src/widgets/widgets/qtoolbarextension.cpp
+++ b/src/widgets/widgets/qtoolbarextension.cpp
@@ -81,7 +81,9 @@ void QToolBarExtension::paintEvent(QPaintEvent *)
QSize QToolBarExtension::sizeHint() const
{
- int ext = style()->pixelMetric(QStyle::PM_ToolBarExtensionExtent);
+ QStyleOption opt;
+ opt.initFrom(this);
+ const int ext = style()->pixelMetric(QStyle::PM_ToolBarExtensionExtent, &opt);
return QSize(ext, ext);
}
diff --git a/src/widgets/widgets/qwidgettextcontrol.cpp b/src/widgets/widgets/qwidgettextcontrol.cpp
index f8bccfbfa3..b68a216af5 100644
--- a/src/widgets/widgets/qwidgettextcontrol.cpp
+++ b/src/widgets/widgets/qwidgettextcontrol.cpp
@@ -2463,7 +2463,7 @@ void QWidgetTextControl::setCursorWidth(int width)
Q_UNUSED(width);
#else
if (width == -1)
- width = QApplication::style()->pixelMetric(QStyle::PM_TextCursorWidth);
+ width = QApplication::style()->pixelMetric(QStyle::PM_TextCursorWidth, nullptr);
d->doc->documentLayout()->setProperty("cursorWidth", width);
#endif
d->repaintCursor();
diff --git a/src/xml/dom/qdom.cpp b/src/xml/dom/qdom.cpp
index 1ac13b380a..39cf0c2653 100644
--- a/src/xml/dom/qdom.cpp
+++ b/src/xml/dom/qdom.cpp
@@ -39,12 +39,13 @@
#include <qplatformdefs.h>
#include <qdom.h>
-#include "qdom_p.h"
-#include "qdomhelpers_p.h"
#include "private/qxmlutils_p.h"
#ifndef QT_NO_DOM
+#include "qdom_p.h"
+#include "qdomhelpers_p.h"
+
#include <qatomic.h>
#include <qbuffer.h>
#include <qiodevice.h>
diff --git a/src/xml/dom/qdomhelpers.cpp b/src/xml/dom/qdomhelpers.cpp
index 10e37f7c0f..63c2db929a 100644
--- a/src/xml/dom/qdomhelpers.cpp
+++ b/src/xml/dom/qdomhelpers.cpp
@@ -37,6 +37,10 @@
**
****************************************************************************/
+#include <QtXml/qtxmlglobal.h>
+
+#ifndef QT_NO_DOM
+
#include "qdomhelpers_p.h"
#include "qdom_p.h"
#include "qxmlstream.h"
@@ -661,3 +665,5 @@ bool QDomParser::parseMarkupDecl()
}
QT_END_NAMESPACE
+
+#endif // QT_NO_DOM
diff --git a/tests/auto/corelib/text/qstring/tst_qstring.cpp b/tests/auto/corelib/text/qstring/tst_qstring.cpp
index ca58b664a0..2c02fb2264 100644
--- a/tests/auto/corelib/text/qstring/tst_qstring.cpp
+++ b/tests/auto/corelib/text/qstring/tst_qstring.cpp
@@ -4684,6 +4684,12 @@ void tst_QString::fromUcs4()
s = QString::fromUcs4(U"\u221212\U000020AC\U00010000");
QCOMPARE(s, QString::fromUtf8("\342\210\222" "12" "\342\202\254" "\360\220\200\200"));
#endif
+
+ // QTBUG-62011: don't mistake ZWNBS for BOM
+ // Start with one BOM, to ensure we use the right endianness:
+ const uint text[] = { 0xfeff, 97, 0xfeff, 98, 0xfeff, 99, 0xfeff, 100 };
+ s = QString::fromUcs4(text, 8);
+ QCOMPARE(s, QStringView(u"a\xfeff" u"b\xfeff" u"c\xfeff" "d"));
}
void tst_QString::toUcs4()
diff --git a/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp b/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp
index 22d96e76f9..771a4d0a32 100644
--- a/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp
+++ b/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp
@@ -45,6 +45,8 @@
#include <algorithm>
+// #define DEBUG_WRITE_OUTPUT
+
typedef QMap<QString, QString> QStringMap;
typedef QList<int> QIntList;
Q_DECLARE_METATYPE(QImage::Format)
@@ -462,24 +464,24 @@ void tst_QImageReader::setScaledClipRect_data()
QTest::addColumn<QRect>("newRect");
QTest::addColumn<QByteArray>("format");
- QTest::newRow("BMP: colorful") << "colorful" << QRect(0, 0, 50, 50) << QByteArray("bmp");
- QTest::newRow("BMP: test32bfv4") << "test32bfv4" << QRect(0, 0, 50, 50) << QByteArray("bmp");
- QTest::newRow("BMP: test32v5") << "test32v5" << QRect(0, 0, 50, 50) << QByteArray("bmp");
- QTest::newRow("BMP: font") << "font" << QRect(0, 0, 50, 50) << QByteArray("bmp");
- QTest::newRow("XPM: marble") << "marble" << QRect(0, 0, 50, 50) << QByteArray("xpm");
- QTest::newRow("PNG: kollada") << "kollada" << QRect(0, 0, 50, 50) << QByteArray("png");
- QTest::newRow("PPM: teapot") << "teapot" << QRect(0, 0, 50, 50) << QByteArray("ppm");
- QTest::newRow("PPM: runners") << "runners.ppm" << QRect(0, 0, 50, 50) << QByteArray("ppm");
- QTest::newRow("PPM: test") << "test.ppm" << QRect(0, 0, 50, 50) << QByteArray("ppm");
- QTest::newRow("XBM: gnus") << "gnus" << QRect(0, 0, 50, 50) << QByteArray("xbm");
+ QTest::newRow("BMP: colorful") << "colorful" << QRect(50, 20, 50, 50) << QByteArray("bmp");
+ QTest::newRow("BMP: test32bfv4") << "test32bfv4" << QRect(50, 20, 50, 50) << QByteArray("bmp");
+ QTest::newRow("BMP: test32v5") << "test32v5" << QRect(50, 20, 50, 50) << QByteArray("bmp");
+ QTest::newRow("BMP: font") << "font" << QRect(50, 20, 50, 50) << QByteArray("bmp");
+ QTest::newRow("XPM: marble") << "marble" << QRect(50, 20, 50, 50) << QByteArray("xpm");
+ QTest::newRow("PNG: kollada") << "kollada" << QRect(50, 20, 50, 50) << QByteArray("png");
+ QTest::newRow("PPM: teapot") << "teapot" << QRect(50, 20, 50, 50) << QByteArray("ppm");
+ QTest::newRow("PPM: runners") << "runners.ppm" << QRect(50, 20, 50, 50) << QByteArray("ppm");
+ QTest::newRow("PPM: test") << "test.ppm" << QRect(50, 20, 50, 50) << QByteArray("ppm");
+ QTest::newRow("XBM: gnus") << "gnus" << QRect(50, 20, 50, 50) << QByteArray("xbm");
- QTest::newRow("JPEG: beavis") << "beavis" << QRect(0, 0, 50, 50) << QByteArray("jpeg");
+ QTest::newRow("JPEG: beavis") << "beavis" << QRect(50, 20, 50, 50) << QByteArray("jpeg");
- QTest::newRow("GIF: earth") << "earth" << QRect(0, 0, 50, 50) << QByteArray("gif");
- QTest::newRow("GIF: trolltech") << "trolltech" << QRect(0, 0, 50, 50) << QByteArray("gif");
+ QTest::newRow("GIF: earth") << "earth" << QRect(50, 20, 50, 50) << QByteArray("gif");
+ QTest::newRow("GIF: trolltech") << "trolltech" << QRect(50, 20, 50, 50) << QByteArray("gif");
- QTest::newRow("SVG: rect") << "rect" << QRect(0, 0, 50, 50) << QByteArray("svg");
- QTest::newRow("SVGZ: rect") << "rect" << QRect(0, 0, 50, 50) << QByteArray("svgz");
+ QTest::newRow("SVG: rect") << "rect" << QRect(50, 20, 50, 50) << QByteArray("svg");
+ QTest::newRow("SVGZ: rect") << "rect" << QRect(50, 20, 50, 50) << QByteArray("svgz");
}
void tst_QImageReader::setScaledClipRect()
@@ -495,7 +497,11 @@ void tst_QImageReader::setScaledClipRect()
reader.setScaledClipRect(newRect);
QImage image = reader.read();
QVERIFY(!image.isNull());
- QCOMPARE(image.rect(), newRect);
+ QCOMPARE(image.rect().translated(50, 20), newRect);
+#ifdef DEBUG_WRITE_OUTPUT
+ QString tempPath = QDir::temp().filePath(fileName) + QLatin1String(".png");
+ image.save(tempPath);
+#endif
QImageReader originalReader(prefix + fileName);
originalReader.setScaledSize(QSize(300, 300));
diff --git a/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp b/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp
index 191260fd41..549481aa21 100644
--- a/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp
+++ b/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp
@@ -75,6 +75,8 @@ private slots:
void nativeHandles();
void nativeTexture_data();
void nativeTexture();
+ void nativeBuffer_data();
+ void nativeBuffer();
void resourceUpdateBatchBuffer_data();
void resourceUpdateBatchBuffer();
void resourceUpdateBatchRGBATextureUpload_data();
@@ -294,7 +296,8 @@ void tst_QRhi::create()
QRhi::BaseInstance,
QRhi::TriangleFanTopology,
QRhi::ReadBackNonUniformBuffer,
- QRhi::ReadBackNonBaseMipLevel
+ QRhi::ReadBackNonBaseMipLevel,
+ QRhi::TexelFetch
};
for (size_t i = 0; i <sizeof(features) / sizeof(QRhi::Feature); ++i)
rhi->isFeatureSupported(features[i]);
@@ -545,6 +548,86 @@ void tst_QRhi::nativeTexture()
}
}
+void tst_QRhi::nativeBuffer_data()
+{
+ rhiTestData();
+}
+
+void tst_QRhi::nativeBuffer()
+{
+ QFETCH(QRhi::Implementation, impl);
+ QFETCH(QRhiInitParams *, initParams);
+
+ QScopedPointer<QRhi> rhi(QRhi::create(impl, initParams, QRhi::Flags(), nullptr));
+ if (!rhi)
+ QSKIP("QRhi could not be created, skipping testing native buffer query");
+
+ const QRhiBuffer::Type types[3] = { QRhiBuffer::Immutable, QRhiBuffer::Static, QRhiBuffer::Dynamic };
+ const QRhiBuffer::UsageFlags usages[3] = { QRhiBuffer::VertexBuffer, QRhiBuffer::IndexBuffer, QRhiBuffer::UniformBuffer };
+ for (int typeUsageIdx = 0; typeUsageIdx < 3; ++typeUsageIdx) {
+ QScopedPointer<QRhiBuffer> buf(rhi->newBuffer(types[typeUsageIdx], usages[typeUsageIdx], 256));
+ QVERIFY(buf->build());
+
+ const QRhiBuffer::NativeBuffer nativeBuf = buf->nativeBuffer();
+ QVERIFY(nativeBuf.slotCount <= rhi->resourceLimit(QRhi::FramesInFlight));
+
+ switch (impl) {
+ case QRhi::Null:
+ break;
+ #ifdef TST_VK
+ case QRhi::Vulkan:
+ {
+ QVERIFY(nativeBuf.slotCount >= 1); // always backed by native buffers
+ for (int i = 0; i < nativeBuf.slotCount; ++i) {
+ auto *buffer = static_cast<const VkBuffer *>(nativeBuf.objects[i]);
+ QVERIFY(buffer);
+ QVERIFY(*buffer);
+ }
+ }
+ break;
+ #endif
+ #ifdef TST_GL
+ case QRhi::OpenGLES2:
+ {
+ QVERIFY(nativeBuf.slotCount >= 0); // UniformBuffers are not backed by native buffers, so 0 is perfectly valid
+ for (int i = 0; i < nativeBuf.slotCount; ++i) {
+ auto *bufferId = static_cast<const uint *>(nativeBuf.objects[i]);
+ QVERIFY(bufferId);
+ QVERIFY(*bufferId);
+ }
+ }
+ break;
+ #endif
+ #ifdef TST_D3D11
+ case QRhi::D3D11:
+ {
+ QVERIFY(nativeBuf.slotCount >= 1); // always backed by native buffers
+ for (int i = 0; i < nativeBuf.slotCount; ++i) {
+ auto *buffer = static_cast<void * const *>(nativeBuf.objects[i]);
+ QVERIFY(buffer);
+ QVERIFY(*buffer);
+ }
+ }
+ break;
+ #endif
+ #ifdef TST_MTL
+ case QRhi::Metal:
+ {
+ QVERIFY(nativeBuf.slotCount >= 1); // always backed by native buffers
+ for (int i = 0; i < nativeBuf.slotCount; ++i) {
+ void * const * buffer = (void * const *) nativeBuf.objects[i];
+ QVERIFY(buffer);
+ QVERIFY(*buffer);
+ }
+ }
+ break;
+ #endif
+ default:
+ Q_ASSERT(false);
+ }
+ }
+}
+
static bool submitResourceUpdates(QRhi *rhi, QRhiResourceUpdateBatch *batch)
{
QRhiCommandBuffer *cb = nullptr;
@@ -1671,9 +1754,9 @@ void tst_QRhi::renderToWindowSimple()
QVERIFY(pipeline->build());
- const int framesInFlight = rhi->resourceLimit(QRhi::FramesInFlight);
- QVERIFY(framesInFlight >= 1);
- const int FRAME_COUNT = framesInFlight + 1;
+ const int asyncReadbackFrames = rhi->resourceLimit(QRhi::MaxAsyncReadbackFrames);
+ // one frame issues the readback, then we do MaxAsyncReadbackFrames more to ensure the readback completes
+ const int FRAME_COUNT = asyncReadbackFrames + 1;
bool readCompleted = false;
QRhiReadbackResult readResult;
QImage result;
@@ -1720,8 +1803,8 @@ void tst_QRhi::renderToWindowSimple()
}
// The readback is asynchronous here. However it is guaranteed that it
- // finished at latest after rendering QRhi::FramesInFlight frames after the
- // one that enqueues the readback.
+ // finished at latest after rendering QRhi::MaxAsyncReadbackFrames frames
+ // after the one that enqueues the readback.
QVERIFY(readCompleted);
QVERIFY(readbackWidth > 0);
diff --git a/tests/auto/gui/text/qfont/tst_qfont.cpp b/tests/auto/gui/text/qfont/tst_qfont.cpp
index 9487436336..2d72eef459 100644
--- a/tests/auto/gui/text/qfont/tst_qfont.cpp
+++ b/tests/auto/gui/text/qfont/tst_qfont.cpp
@@ -314,27 +314,33 @@ void tst_QFont::resolve()
void tst_QFont::resetFont()
{
QWidget parent;
+ QWidget firstChild(&parent);
QFont parentFont = parent.font();
parentFont.setPointSize(parentFont.pointSize() + 2);
parent.setFont(parentFont);
- QWidget *child = new QWidget(&parent);
-
- QFont childFont = child->font();
+ QFont childFont = firstChild.font();
childFont.setBold(!childFont.bold());
- child->setFont(childFont);
+ firstChild.setFont(childFont);
+
+ QWidget secondChild(&parent);
+ secondChild.setFont(childFont);
QVERIFY(parentFont.resolve() != 0);
QVERIFY(childFont.resolve() != 0);
QVERIFY(childFont != parentFont);
- child->setFont(QFont()); // reset font
+ // reset font on both children
+ firstChild.setFont(QFont());
+ secondChild.setFont(QFont());
- QCOMPARE(child->font().resolve(), uint(0));
+ QCOMPARE(firstChild.font().resolve(), QFont::SizeResolved);
+ QCOMPARE(secondChild.font().resolve(), QFont::SizeResolved);
#ifdef Q_OS_ANDROID
QEXPECT_FAIL("", "QTBUG-69214", Continue);
#endif
- QCOMPARE(child->font().pointSize(), parent.font().pointSize());
+ QCOMPARE(firstChild.font().pointSize(), parent.font().pointSize());
+ QCOMPARE(secondChild.font().pointSize(), parent.font().pointSize());
QVERIFY(parent.font().resolve() != 0);
}
#endif
diff --git a/tests/auto/gui/util/qshadergenerator/tst_qshadergenerator.cpp b/tests/auto/gui/util/qshadergenerator/tst_qshadergenerator.cpp
index 59e93d127f..56df69dde8 100644
--- a/tests/auto/gui/util/qshadergenerator/tst_qshadergenerator.cpp
+++ b/tests/auto/gui/util/qshadergenerator/tst_qshadergenerator.cpp
@@ -198,6 +198,9 @@ private slots:
void shouldGenerateDifferentCodeDependingOnActiveLayers();
void shouldUseGlobalVariableRatherThanTemporaries();
void shouldGenerateTemporariesWisely();
+ void shouldHandlePortNamesPrefixingOneAnother();
+ void shouldHandleNodesWithMultipleOutputPorts();
+ void shouldHandleExpressionsInInputNodes();
};
void tst_QShaderGenerator::shouldHaveDefaultState()
@@ -1229,6 +1232,196 @@ void tst_QShaderGenerator::shouldGenerateTemporariesWisely()
}
}
+void tst_QShaderGenerator::shouldHandlePortNamesPrefixingOneAnother()
+{
+ // GIVEN
+ const auto gl4 = createFormat(QShaderFormat::OpenGLCoreProfile, 4, 0);
+
+ auto color1 = createNode({
+ createPort(QShaderNodePort::Output, "output")
+ });
+ color1.addRule(gl4, QShaderNode::Rule("vec4 $output = color1;",
+ QByteArrayList() << "in vec4 color1;"));
+
+ auto color2 = createNode({
+ createPort(QShaderNodePort::Output, "output")
+ });
+ color2.addRule(gl4, QShaderNode::Rule("vec4 $output = color2;",
+ QByteArrayList() << "in vec4 color2;"));
+
+ auto addColor = createNode({
+ createPort(QShaderNodePort::Output, "color"),
+ createPort(QShaderNodePort::Input, "color1"),
+ createPort(QShaderNodePort::Input, "color2"),
+ });
+ addColor.addRule(gl4, QShaderNode::Rule("vec4 $color = $color1 + $color2;"));
+
+ auto shaderOutput = createNode({
+ createPort(QShaderNodePort::Input, "input")
+ });
+
+ shaderOutput.addRule(gl4, QShaderNode::Rule("shaderOutput = $input;",
+ QByteArrayList() << "out vec4 shaderOutput;"));
+
+ // WHEN
+ const auto graph = [=] {
+ auto res = QShaderGraph();
+
+ res.addNode(color1);
+ res.addNode(color2);
+ res.addNode(addColor);
+ res.addNode(shaderOutput);
+
+ res.addEdge(createEdge(color1.uuid(), "output", addColor.uuid(), "color1"));
+ res.addEdge(createEdge(color2.uuid(), "output", addColor.uuid(), "color2"));
+ res.addEdge(createEdge(addColor.uuid(), "color", shaderOutput.uuid(), "input"));
+
+ return res;
+ }();
+
+ auto generator = QShaderGenerator();
+ generator.graph = graph;
+ generator.format = gl4;
+
+ const auto code = generator.createShaderCode();
+
+ // THEN
+ const auto expected = QByteArrayList()
+ << "#version 400 core"
+ << ""
+ << "in vec4 color1;"
+ << "in vec4 color2;"
+ << "out vec4 shaderOutput;"
+ << ""
+ << "void main()"
+ << "{"
+ << " shaderOutput = ((color1 + color2));"
+ << "}"
+ << "";
+ QCOMPARE(code, expected.join("\n"));
+}
+
+void tst_QShaderGenerator::shouldHandleNodesWithMultipleOutputPorts()
+{
+ // GIVEN
+ const auto gl4 = createFormat(QShaderFormat::OpenGLCoreProfile, 4, 0);
+
+ auto input = createNode({
+ createPort(QShaderNodePort::Output, "output0"),
+ createPort(QShaderNodePort::Output, "output1")
+ });
+ input.addRule(gl4, QShaderNode::Rule("vec4 $output0 = globalIn0;"
+ "float $output1 = globalIn1;",
+ QByteArrayList() << "in vec4 globalIn0;" << "in float globalIn1;"));
+
+ auto function = createNode({
+ createPort(QShaderNodePort::Input, "input0"),
+ createPort(QShaderNodePort::Input, "input1"),
+ createPort(QShaderNodePort::Output, "output0"),
+ createPort(QShaderNodePort::Output, "output1")
+ });
+ function.addRule(gl4, QShaderNode::Rule("vec4 $output0 = $input0;"
+ "float $output1 = $input1;"));
+
+ auto output = createNode({
+ createPort(QShaderNodePort::Input, "input0"),
+ createPort(QShaderNodePort::Input, "input1")
+ });
+
+ output.addRule(gl4, QShaderNode::Rule("globalOut0 = $input0;"
+ "globalOut1 = $input1;",
+ QByteArrayList() << "out vec4 globalOut0;" << "out float globalOut1;"));
+
+ // WHEN
+ const auto graph = [=] {
+ auto res = QShaderGraph();
+
+ res.addNode(input);
+ res.addNode(function);
+ res.addNode(output);
+
+ res.addEdge(createEdge(input.uuid(), "output0", function.uuid(), "input0"));
+ res.addEdge(createEdge(input.uuid(), "output1", function.uuid(), "input1"));
+
+ res.addEdge(createEdge(function.uuid(), "output0", output.uuid(), "input0"));
+ res.addEdge(createEdge(function.uuid(), "output1", output.uuid(), "input1"));
+
+ return res;
+ }();
+
+ auto generator = QShaderGenerator();
+ generator.graph = graph;
+ generator.format = gl4;
+
+ const auto code = generator.createShaderCode();
+
+ // THEN
+ const auto expected = QByteArrayList()
+ << "#version 400 core"
+ << ""
+ << "in vec4 globalIn0;"
+ << "in float globalIn1;"
+ << "out vec4 globalOut0;"
+ << "out float globalOut1;"
+ << ""
+ << "void main()"
+ << "{"
+ << " globalOut0 = globalIn0;"
+ << " globalOut1 = globalIn1;"
+ << "}"
+ << "";
+ QCOMPARE(code, expected.join("\n"));
+}
+
+void tst_QShaderGenerator::shouldHandleExpressionsInInputNodes()
+{
+ // GIVEN
+ const auto gl4 = createFormat(QShaderFormat::OpenGLCoreProfile, 4, 0);
+
+ auto input = createNode({
+ createPort(QShaderNodePort::Output, "output")
+ });
+ input.addRule(gl4, QShaderNode::Rule("float $output = 3 + 4;"));
+
+ auto output = createNode({
+ createPort(QShaderNodePort::Input, "input")
+ });
+
+ output.addRule(gl4, QShaderNode::Rule("globalOut = $input;",
+ QByteArrayList() << "out float globalOut;"));
+
+ // WHEN
+ const auto graph = [=] {
+ auto res = QShaderGraph();
+
+ res.addNode(input);
+ res.addNode(output);
+
+ res.addEdge(createEdge(input.uuid(), "output", output.uuid(), "input"));
+
+ return res;
+ }();
+
+ auto generator = QShaderGenerator();
+ generator.graph = graph;
+ generator.format = gl4;
+
+ const auto code = generator.createShaderCode();
+
+ // THEN
+ const auto expected = QByteArrayList()
+ << "#version 400 core"
+ << ""
+ << "out float globalOut;"
+ << ""
+ << "void main()"
+ << "{"
+ << " globalOut = 3 + 4;"
+ << "}"
+ << "";
+ QCOMPARE(code, expected.join("\n"));
+}
+
QTEST_MAIN(tst_QShaderGenerator)
#include "tst_qshadergenerator.moc"
diff --git a/tests/auto/gui/util/qshadergraph/tst_qshadergraph.cpp b/tests/auto/gui/util/qshadergraph/tst_qshadergraph.cpp
index ce2d38c24f..014a163f58 100644
--- a/tests/auto/gui/util/qshadergraph/tst_qshadergraph.cpp
+++ b/tests/auto/gui/util/qshadergraph/tst_qshadergraph.cpp
@@ -114,6 +114,7 @@ private slots:
void shouldSurviveCyclesDuringGraphSerialization();
void shouldDealWithEdgesJumpingOverLayers();
void shouldGenerateDifferentStatementsDependingOnActiveLayers();
+ void shouldDealWithBranchesWithoutOutput();
};
void tst_QShaderGraph::shouldHaveEdgeDefaultState()
@@ -515,12 +516,9 @@ void tst_QShaderGraph::shouldHandleUnboundPortsDuringGraphSerialization()
const auto statements = graph.createStatements();
// THEN
- // Note that no edge leads to the unbound input
+ // Note that no statement has any unbound input
const auto expected = QVector<QShaderGraph::Statement>()
- << createStatement(input, {}, {0})
- << createStatement(function, {-1, 0, -1}, {2, 3, 4})
- << createStatement(unboundOutput, {-1}, {})
- << createStatement(output, {3}, {});
+ << createStatement(input, {}, {0});
dumpStatementsIfNeeded(statements, expected);
QCOMPARE(statements, expected);
}
@@ -567,9 +565,8 @@ void tst_QShaderGraph::shouldSurviveCyclesDuringGraphSerialization()
const auto statements = graph.createStatements();
// THEN
- // Obviously will lead to a compile failure later on since it cuts everything beyond the cycle
- const auto expected = QVector<QShaderGraph::Statement>()
- << createStatement(output, {2}, {});
+ // The cycle is ignored
+ const auto expected = QVector<QShaderGraph::Statement>();
dumpStatementsIfNeeded(statements, expected);
QCOMPARE(statements, expected);
}
@@ -774,6 +771,50 @@ void tst_QShaderGraph::shouldGenerateDifferentStatementsDependingOnActiveLayers(
}
}
+void tst_QShaderGraph::shouldDealWithBranchesWithoutOutput()
+{
+ // GIVEN
+ const auto input = createNode({
+ createPort(QShaderNodePort::Output, "input")
+ });
+ const auto output = createNode({
+ createPort(QShaderNodePort::Input, "output")
+ });
+ const auto danglingFunction = createNode({
+ createPort(QShaderNodePort::Input, "functionInput"),
+ createPort(QShaderNodePort::Output, "unbound")
+ });
+ const auto function = createNode({
+ createPort(QShaderNodePort::Input, "functionInput"),
+ createPort(QShaderNodePort::Output, "functionOutput")
+ });
+
+ const auto graph = [=] {
+ auto res = QShaderGraph();
+ res.addNode(input);
+ res.addNode(function);
+ res.addNode(danglingFunction);
+ res.addNode(output);
+ res.addEdge(createEdge(input.uuid(), "input", function.uuid(), "functionInput"));
+ res.addEdge(createEdge(input.uuid(), "input", danglingFunction.uuid(), "functionInput"));
+ res.addEdge(createEdge(function.uuid(), "functionOutput", output.uuid(), "output"));
+ return res;
+ }();
+
+ // WHEN
+ const auto statements = graph.createStatements();
+
+ // THEN
+ // Note that no edge leads to the unbound input
+ const auto expected = QVector<QShaderGraph::Statement>()
+ << createStatement(input, {}, {0})
+ << createStatement(function, {0}, {1})
+ << createStatement(output, {1}, {})
+ << createStatement(danglingFunction, {0}, {2});
+ dumpStatementsIfNeeded(statements, expected);
+ QCOMPARE(statements, expected);
+}
+
QTEST_MAIN(tst_QShaderGraph)
#include "tst_qshadergraph.moc"
diff --git a/tests/auto/network-settings.h b/tests/auto/network-settings.h
index 65d4bb5cea..641bf1d672 100644
--- a/tests/auto/network-settings.h
+++ b/tests/auto/network-settings.h
@@ -134,6 +134,22 @@ public:
return true;
}
+ static bool canBindToLowPorts()
+ {
+#ifdef Q_OS_UNIX
+ if (geteuid() == 0)
+ return true;
+ if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::MacOSMojave)
+ return true;
+ // ### Which versions of iOS, watchOS and such does Apple's opening of
+ // all ports apply to?
+ return false;
+#else
+ // Windows
+ return true;
+#endif
+ }
+
#ifdef QT_NETWORK_LIB
static bool verifyTestNetworkSettings()
diff --git a/tests/auto/network/socket/platformsocketengine/tst_platformsocketengine.cpp b/tests/auto/network/socket/platformsocketengine/tst_platformsocketengine.cpp
index 1ef9382f0a..68c913ecfc 100644
--- a/tests/auto/network/socket/platformsocketengine/tst_platformsocketengine.cpp
+++ b/tests/auto/network/socket/platformsocketengine/tst_platformsocketengine.cpp
@@ -529,18 +529,11 @@ void tst_PlatformSocketEngine::tooManySockets()
//---------------------------------------------------------------------------
void tst_PlatformSocketEngine::bind()
{
-#if !defined Q_OS_WIN
-#if defined Q_OS_MACOS
- // On macOS >= 10.14 the bind on this port is successful.
- if (QOperatingSystemVersion::current() < QOperatingSystemVersion::MacOSMojave)
-#endif // Q_OS_MACOS
- {
- PLATFORMSOCKETENGINE binder;
- QVERIFY(binder.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol));
- QVERIFY(!binder.bind(QHostAddress::AnyIPv4, 82));
+ PLATFORMSOCKETENGINE binder;
+ QVERIFY(binder.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol));
+ QCOMPARE(binder.bind(QHostAddress::AnyIPv4, 82), QtNetworkSettings::canBindToLowPorts());
+ if (!QtNetworkSettings::canBindToLowPorts())
QCOMPARE(binder.error(), QAbstractSocket::SocketAccessError);
- }
-#endif // Q_OS_WIN
PLATFORMSOCKETENGINE binder2;
QVERIFY(binder2.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol));
@@ -552,6 +545,12 @@ void tst_PlatformSocketEngine::bind()
QCOMPARE(binder3.error(), QAbstractSocket::AddressInUseError);
if (QtNetworkSettings::hasIPv6()) {
+ PLATFORMSOCKETENGINE binder;
+ QVERIFY(binder.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv6Protocol));
+ QCOMPARE(binder.bind(QHostAddress::AnyIPv6, 82), QtNetworkSettings::canBindToLowPorts());
+ if (!QtNetworkSettings::canBindToLowPorts())
+ QCOMPARE(binder.error(), QAbstractSocket::SocketAccessError);
+
PLATFORMSOCKETENGINE binder4;
QVERIFY(binder4.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv6Protocol));
QVERIFY(binder4.bind(QHostAddress::AnyIPv6, 31180));
diff --git a/tests/auto/network/socket/qtcpsocket/BLACKLIST b/tests/auto/network/socket/qtcpsocket/BLACKLIST
index 07532710b3..129e9f0b4e 100644
--- a/tests/auto/network/socket/qtcpsocket/BLACKLIST
+++ b/tests/auto/network/socket/qtcpsocket/BLACKLIST
@@ -1,10 +1,3 @@
-[bind]
-windows-10 msvc-2015
-windows-7sp1
-[bind:[::]]
-windows
-[bind:[::]:randomport]
-windows
[timeoutConnect:ip]
windows
# QTBUG-66247
diff --git a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp
index bf08d70eb3..099aa5fb51 100644
--- a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp
+++ b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp
@@ -523,7 +523,7 @@ void tst_QTcpSocket::bind_data()
continue; // link-local bind will fail, at least on Linux, so skip it.
QString ip(entry.ip().toString());
- QTest::newRow(ip.toLatin1().constData()) << ip << 0 << true << ip;
+ QTest::addRow("%s:0", ip.toLatin1().constData()) << ip << 0 << true << ip;
if (!testIpv6 && entry.ip().protocol() == QAbstractSocket::IPv6Protocol)
testIpv6 = true;
@@ -531,9 +531,9 @@ void tst_QTcpSocket::bind_data()
}
// test binding to localhost
- QTest::newRow("0.0.0.0") << "0.0.0.0" << 0 << true << "0.0.0.0";
+ QTest::newRow("0.0.0.0:0") << "0.0.0.0" << 0 << true << "0.0.0.0";
if (testIpv6)
- QTest::newRow("[::]") << "::" << 0 << true << "::";
+ QTest::newRow("[::]:0") << "::" << 0 << true << "::";
// and binding with a port number...
// Since we want to test that we got the port number we asked for, we need a random port number.
@@ -551,26 +551,22 @@ void tst_QTcpSocket::bind_data()
knownBad << "198.51.100.1";
knownBad << "2001:0DB8::1";
foreach (const QString &badAddress, knownBad) {
- QTest::newRow(badAddress.toLatin1().constData()) << badAddress << 0 << false << QString();
+ QTest::addRow("%s:0", badAddress.toLatin1().constData()) << badAddress << 0 << false << QString();
}
-#ifdef Q_OS_UNIX
// try to bind to a privileged ports
// we should fail if we're not root (unless the ports are in use!)
- QTest::newRow("127.0.0.1:1") << "127.0.0.1" << 1 << !geteuid() << (geteuid() ? QString() : "127.0.0.1");
- if (testIpv6) {
#ifdef Q_OS_DARWIN
- // This case is faling in different ways, first, it manages to bind to
- // port 1 on macOS >= 10.14, but if we change the logic to not fail,
- // it's becoming flaky and sometimes fails to bind, with error 'port in use'
- // (apparently inflicted by the previous test row with 127.0.0.1). Amen.
- if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::MacOSMojave)
- QTest::qWarn("Skipping [::]:1, see QTBUG-81905", __FILE__, __LINE__);
- else
+ // Alas, some quirk (starting from macOS 10.14): bind with port number 1
+ // fails with IPv4 (not IPv6 though, see below).
+ QTest::newRow("127.0.0.1:1") << "127.0.0.1" << 1 << false << QString();
+#else
+ QTest::newRow("127.0.0.1:1") << "127.0.0.1" << 1 << QtNetworkSettings::canBindToLowPorts()
+ << (QtNetworkSettings::canBindToLowPorts() ? "127.0.0.1" : QString());
#endif // Q_OS_DARWIN
- QTest::newRow("[::]:1") << "::" << 1 << !geteuid() << (geteuid() ? QString() : "::");
- }
-#endif
+ if (testIpv6)
+ QTest::newRow("[::]:1") << "::" << 1 << QtNetworkSettings::canBindToLowPorts()
+ << (QtNetworkSettings::canBindToLowPorts() ? "::" : QString());
}
void tst_QTcpSocket::bind()
@@ -589,13 +585,13 @@ void tst_QTcpSocket::bind()
QTcpSocket dummySocket; // used only to "use up" a file descriptor
dummySocket.bind();
- QTcpSocket *socket = newSocket();
+ std::unique_ptr<QTcpSocket> socket(newSocket());
quint16 boundPort;
qintptr fd;
if (successExpected) {
bool randomPort = port == -1;
- int attemptsLeft = 5; // only used with randomPort
+ int attemptsLeft = 5; // only used with randomPort or Windows
do {
if (randomPort) {
// try to get a random port number
@@ -655,9 +651,24 @@ void tst_QTcpSocket::bind()
QCOMPARE(acceptedSocket->peerPort(), boundPort);
QCOMPARE(socket->localAddress(), remoteAddr);
QCOMPARE(socket->socketDescriptor(), fd);
+#ifdef Q_OS_DARWIN
+ // Normally, we don't see this problem: macOS sometimes does not
+ // allow us to immediately re-use a port, thinking connection is
+ // still alive. With fixed port 1 (we testing starting from
+ // macOS 10.14), this problem shows, making the test flaky:
+ // we run this 'bind' with port 1 several times (different
+ // test cases) and the problem manifests itself as
+ // "The bound address is already in use, tried port 1".
+ QTestEventLoop cleanupHelper;
+ auto client = socket.get();
+ connect(client, &QTcpSocket::disconnected, [&cleanupHelper, client](){
+ client->close();
+ cleanupHelper.exitLoop();
+ });
+ acceptedSocket->close();
+ cleanupHelper.enterLoopMSecs(100);
+#endif // Q_OS_DARWIN
}
-
- delete socket;
}
//----------------------------------------------------------------------------------
diff --git a/tests/auto/tools/moc/allmocs_baseline_in.json b/tests/auto/tools/moc/allmocs_baseline_in.json
index 4f57fad5a8..9cc06dc7bc 100644
--- a/tests/auto/tools/moc/allmocs_baseline_in.json
+++ b/tests/auto/tools/moc/allmocs_baseline_in.json
@@ -3,6 +3,7 @@
"classes": [
{
"className": "BackslashNewlines",
+ "object": true,
"qualifiedClassName": "BackslashNewlines",
"slots": [
{
@@ -26,6 +27,7 @@
"classes": [
{
"className": "IfdefedClass",
+ "object": true,
"qualifiedClassName": "IfdefedClass",
"superClasses": [
{
@@ -239,6 +241,7 @@
"classes": [
{
"className": "ExplicitOverrideControlBase",
+ "object": true,
"qualifiedClassName": "ExplicitOverrideControlBase",
"slots": [
{
@@ -271,6 +274,7 @@
},
{
"className": "ExplicitOverrideControlFinalQt",
+ "object": true,
"qualifiedClassName": "ExplicitOverrideControlFinalQt",
"slots": [
{
@@ -303,6 +307,7 @@
},
{
"className": "ExplicitOverrideControlFinalCxx11",
+ "object": true,
"qualifiedClassName": "ExplicitOverrideControlFinalCxx11",
"slots": [
{
@@ -335,6 +340,7 @@
},
{
"className": "ExplicitOverrideControlSealed",
+ "object": true,
"qualifiedClassName": "ExplicitOverrideControlSealed",
"slots": [
{
@@ -367,6 +373,7 @@
},
{
"className": "ExplicitOverrideControlOverrideQt",
+ "object": true,
"qualifiedClassName": "ExplicitOverrideControlOverrideQt",
"slots": [
{
@@ -399,6 +406,7 @@
},
{
"className": "ExplicitOverrideControlOverrideCxx11",
+ "object": true,
"qualifiedClassName": "ExplicitOverrideControlOverrideCxx11",
"slots": [
{
@@ -431,6 +439,7 @@
},
{
"className": "ExplicitOverrideControlFinalQtOverrideQt",
+ "object": true,
"qualifiedClassName": "ExplicitOverrideControlFinalQtOverrideQt",
"slots": [
{
@@ -463,6 +472,7 @@
},
{
"className": "ExplicitOverrideControlFinalCxx11OverrideCxx11",
+ "object": true,
"qualifiedClassName": "ExplicitOverrideControlFinalCxx11OverrideCxx11",
"slots": [
{
@@ -495,6 +505,7 @@
},
{
"className": "ExplicitOverrideControlSealedOverride",
+ "object": true,
"qualifiedClassName": "ExplicitOverrideControlSealedOverride",
"slots": [
{
@@ -533,6 +544,7 @@
"classes": [
{
"className": "FinalTestClassQt",
+ "object": true,
"qualifiedClassName": "FinalTestClassQt",
"superClasses": [
{
@@ -543,6 +555,7 @@
},
{
"className": "ExportedFinalTestClassQt",
+ "object": true,
"qualifiedClassName": "ExportedFinalTestClassQt",
"superClasses": [
{
@@ -553,6 +566,7 @@
},
{
"className": "ExportedFinalTestClassQtX",
+ "object": true,
"qualifiedClassName": "ExportedFinalTestClassQtX",
"superClasses": [
{
@@ -563,6 +577,7 @@
},
{
"className": "FinalTestClassCpp11",
+ "object": true,
"qualifiedClassName": "FinalTestClassCpp11",
"superClasses": [
{
@@ -573,6 +588,7 @@
},
{
"className": "ExportedFinalTestClassCpp11",
+ "object": true,
"qualifiedClassName": "ExportedFinalTestClassCpp11",
"superClasses": [
{
@@ -583,6 +599,7 @@
},
{
"className": "ExportedFinalTestClassCpp11X",
+ "object": true,
"qualifiedClassName": "ExportedFinalTestClassCpp11X",
"superClasses": [
{
@@ -593,6 +610,7 @@
},
{
"className": "SealedTestClass",
+ "object": true,
"qualifiedClassName": "SealedTestClass",
"superClasses": [
{
@@ -603,6 +621,7 @@
},
{
"className": "ExportedSealedTestClass",
+ "object": true,
"qualifiedClassName": "ExportedSealedTestClass",
"superClasses": [
{
@@ -613,6 +632,7 @@
},
{
"className": "ExportedSealedTestClassX",
+ "object": true,
"qualifiedClassName": "ExportedSealedTestClassX",
"superClasses": [
{
@@ -654,7 +674,7 @@
]
}
],
- "gadget": true,
+ "namespace": true,
"qualifiedClassName": "CXX17Namespace::A::B::C::D"
}
],
@@ -673,6 +693,7 @@
}
]
],
+ "object": true,
"qualifiedClassName": "DirInIncludePath",
"superClasses": [
{
@@ -707,6 +728,7 @@
}
],
"className": "StringLiterals",
+ "object": true,
"qualifiedClassName": "StringLiterals",
"superClasses": [
{
@@ -723,6 +745,7 @@
"classes": [
{
"className": "ForwardDeclaredParamClass",
+ "object": true,
"qualifiedClassName": "ForwardDeclaredParamClass",
"signals": [
{
@@ -923,6 +946,7 @@
"classes": [
{
"className": "FunctionWithAttributes",
+ "object": true,
"qualifiedClassName": "FunctionWithAttributes",
"slots": [
{
@@ -1016,6 +1040,7 @@
"classes": [
{
"className": "TestFwdProperties",
+ "object": true,
"properties": [
{
"constant": false,
@@ -1067,7 +1092,7 @@
},
{
"className": "SomeRandomNamespace",
- "gadget": true,
+ "namespace": true,
"qualifiedClassName": "SomeRandomNamespace"
}
],
@@ -1089,7 +1114,7 @@
]
}
],
- "gadget": true,
+ "namespace": true,
"qualifiedClassName": "FooNamespace"
},
{
@@ -1114,7 +1139,7 @@
]
}
],
- "gadget": true,
+ "namespace": true,
"qualifiedClassName": "FooNamespace::FooNestedNamespace"
},
{
@@ -1130,7 +1155,7 @@
]
}
],
- "gadget": true,
+ "namespace": true,
"qualifiedClassName": "FooNamespace::FooNestedNamespace::FooMoreNestedNamespace"
}
],
@@ -1153,6 +1178,7 @@
]
}
],
+ "object": true,
"properties": [
{
"constant": false,
@@ -1178,6 +1204,7 @@
},
{
"className": "Baz",
+ "object": true,
"properties": [
{
"constant": false,
@@ -1222,6 +1249,7 @@
"classes": [
{
"className": "MyBooooooostishClass",
+ "object": true,
"qualifiedClassName": "MyBooooooostishClass",
"signals": [
{
@@ -1269,6 +1297,7 @@
"classes": [
{
"className": "OldStyleCast",
+ "object": true,
"qualifiedClassName": "OldStyleCast",
"slots": [
{
@@ -1341,6 +1370,7 @@
}
],
"className": "ParseDefine",
+ "object": true,
"qualifiedClassName": "PD::ParseDefine",
"signals": [
{
@@ -1526,6 +1556,7 @@
"classes": [
{
"className": "TestPluginMetaData",
+ "object": true,
"qualifiedClassName": "TestPluginMetaData",
"superClasses": [
{
@@ -1542,6 +1573,7 @@
"classes": [
{
"className": "PureVirtualSignalsTest",
+ "object": true,
"qualifiedClassName": "PureVirtualSignalsTest",
"signals": [
{
@@ -1575,6 +1607,7 @@
},
{
"className": "PureVirtualSignalsImpl",
+ "object": true,
"qualifiedClassName": "PureVirtualSignalsImpl",
"signals": [
{
@@ -1616,6 +1649,7 @@
"returnType": "const char*"
}
],
+ "object": true,
"qualifiedClassName": "InvokableBeforeReturnType",
"superClasses": [
{
@@ -1638,6 +1672,7 @@
"returnType": "void"
}
],
+ "object": true,
"qualifiedClassName": "InvokableBeforeInline",
"superClasses": [
{
@@ -1661,6 +1696,7 @@
"returnType": "void"
}
],
+ "object": true,
"qualifiedClassName": "TestQPrivateSlots",
"slots": [
{
@@ -1705,6 +1741,7 @@
"classes": [
{
"className": "B",
+ "object": true,
"properties": [
{
"constant": false,
@@ -1745,6 +1782,7 @@
]
}
],
+ "object": true,
"qualifiedClassName": "QTBUG_2151::A",
"superClasses": [
{
@@ -1755,6 +1793,7 @@
},
{
"className": "B",
+ "object": true,
"properties": [
{
"constant": false,
@@ -1810,6 +1849,7 @@
]
}
],
+ "object": true,
"qualifiedClassName": "Unsused::Object",
"superClasses": [
{
@@ -1845,6 +1885,7 @@
]
}
],
+ "object": true,
"qualifiedClassName": "NS1::Nested::Object",
"superClasses": [
{
@@ -1880,6 +1921,7 @@
]
}
],
+ "object": true,
"qualifiedClassName": "NS1::NestedUnsused::Object",
"superClasses": [
{
@@ -1915,6 +1957,7 @@
]
}
],
+ "object": true,
"qualifiedClassName": "NS1::Object",
"superClasses": [
{
@@ -1925,6 +1968,7 @@
},
{
"className": "DependingObject",
+ "object": true,
"properties": [
{
"constant": false,
@@ -1961,6 +2005,7 @@
},
{
"className": "DependingNestedGadget",
+ "object": true,
"properties": [
{
"constant": false,
@@ -1985,6 +2030,7 @@
},
{
"className": "DependingNestedObject",
+ "object": true,
"properties": [
{
"constant": false,
@@ -2034,6 +2080,7 @@
]
}
],
+ "object": true,
"qualifiedClassName": "NS2::Nested::Object",
"superClasses": [
{
@@ -2069,6 +2116,7 @@
]
}
],
+ "object": true,
"qualifiedClassName": "NS2::NestedUnsused::Object",
"superClasses": [
{
@@ -2104,6 +2152,7 @@
]
}
],
+ "object": true,
"qualifiedClassName": "NS2::Object",
"superClasses": [
{
@@ -2114,6 +2163,7 @@
},
{
"className": "DependingObject",
+ "object": true,
"properties": [
{
"constant": false,
@@ -2150,6 +2200,7 @@
},
{
"className": "DependingNestedGadget",
+ "object": true,
"properties": [
{
"constant": false,
@@ -2174,6 +2225,7 @@
},
{
"className": "DependingNestedObject",
+ "object": true,
"properties": [
{
"constant": false,
@@ -2214,6 +2266,7 @@
]
}
],
+ "object": true,
"qualifiedClassName": "KDAB",
"superClasses": [
{
@@ -2230,6 +2283,7 @@
"classes": [
{
"className": "SingleFunctionKeywordBeforeReturnType",
+ "object": true,
"qualifiedClassName": "SingleFunctionKeywordBeforeReturnType",
"signals": [
{
@@ -2254,6 +2308,7 @@
},
{
"className": "SingleFunctionKeywordBeforeInline",
+ "object": true,
"qualifiedClassName": "SingleFunctionKeywordBeforeInline",
"signals": [
{
@@ -2278,6 +2333,7 @@
},
{
"className": "SingleFunctionKeywordAfterInline",
+ "object": true,
"qualifiedClassName": "SingleFunctionKeywordAfterInline",
"signals": [
{
@@ -2308,6 +2364,7 @@
"classes": [
{
"className": "SlotsWithVoidTemplateTest",
+ "object": true,
"qualifiedClassName": "SlotsWithVoidTemplateTest",
"signals": [
{
@@ -2373,6 +2430,7 @@
"classes": [
{
"className": "Task192552",
+ "object": true,
"qualifiedClassName": "Task192552",
"superClasses": [
{
@@ -2389,6 +2447,7 @@
"classes": [
{
"className": "TestObject",
+ "object": true,
"qualifiedClassName": "NS_A::NS_B::TestObject",
"superClasses": [
{
@@ -2399,6 +2458,7 @@
},
{
"className": "TestMain",
+ "object": true,
"qualifiedClassName": "NS_A::NS_Main::TestMain",
"superClasses": [
{
@@ -2415,6 +2475,7 @@
"classes": [
{
"className": "TypenameWithUnsigned",
+ "object": true,
"qualifiedClassName": "TypenameWithUnsigned",
"slots": [
{
@@ -2564,6 +2625,7 @@
"classes": [
{
"className": "Task87883",
+ "object": true,
"qualifiedClassName": "Task87883",
"superClasses": [
{
@@ -2580,6 +2642,7 @@
"classes": [
{
"className": "Foo",
+ "object": true,
"qualifiedClassName": "BBB::Foo",
"signals": [
{
diff --git a/tests/auto/widgets/dialogs/qfilesystemmodel/BLACKLIST b/tests/auto/widgets/dialogs/qfilesystemmodel/BLACKLIST
index aae2cacc3b..d9d7786314 100644
--- a/tests/auto/widgets/dialogs/qfilesystemmodel/BLACKLIST
+++ b/tests/auto/widgets/dialogs/qfilesystemmodel/BLACKLIST
@@ -8,9 +8,5 @@ b2qt
b2qt
[dirsBeforeFiles]
winrt
-b2qt
-ubuntu
-windows-10
-rhel
[drives]
winrt
diff --git a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp
index 8396fd4ec7..7259fa1ab0 100644
--- a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp
+++ b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp
@@ -976,6 +976,7 @@ void tst_QTreeView::indexWidget()
QStandardItemModel treeModel;
initStandardTreeModel(&treeModel);
view.setModel(&treeModel);
+ view.resize(300, 400); // make sure the width of the view is larger than the widgets below
QModelIndex index = view.model()->index(0, 0);
@@ -1004,6 +1005,7 @@ void tst_QTreeView::indexWidget()
//now let's try to do that later when the widget is already shown
view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
index = view.model()->index(1, 0);
QVERIFY(!view.indexWidget(index));
diff --git a/tests/auto/widgets/kernel/qwidget/hellotr_la.qm b/tests/auto/widgets/kernel/qwidget/hellotr_la.qm
new file mode 100644
index 0000000000..25c0aad583
--- /dev/null
+++ b/tests/auto/widgets/kernel/qwidget/hellotr_la.qm
Binary files differ
diff --git a/tests/auto/widgets/kernel/qwidget/qwidget.qrc b/tests/auto/widgets/kernel/qwidget/qwidget.qrc
index 1399c4c9db..597ea872a5 100644
--- a/tests/auto/widgets/kernel/qwidget/qwidget.qrc
+++ b/tests/auto/widgets/kernel/qwidget/qwidget.qrc
@@ -3,5 +3,6 @@
<file>geometry.dat</file>
<file>geometry-maximized.dat</file>
<file>geometry-fullscreen.dat</file>
+ <file>hellotr_la.qm</file>
</qresource>
</RCC>
diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
index 9c16b1a00a..f0c490b598 100644
--- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
+++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
@@ -162,8 +162,10 @@ private slots:
void fontPropagation();
void fontPropagation2();
void fontPropagation3();
+ void fontPropagationDynamic();
void palettePropagation();
void palettePropagation2();
+ void palettePropagationDynamic();
void enabledPropagation();
void ignoreKeyEventsWhenDisabled_QTBUG27417();
void properTabHandlingWhenDisabled_QTBUG27417();
@@ -310,6 +312,8 @@ private slots:
void hideOpaqueChildWhileHidden();
void updateWhileMinimized();
void alienWidgets();
+ void nativeWindowPosition_data();
+ void nativeWindowPosition();
void adjustSize();
void adjustSize_data();
void updateGeometry();
@@ -410,6 +414,7 @@ private slots:
void closeWithChildWindow();
void winIdAfterClose();
+ void receivesLanguageChangeEvent();
private:
bool ensureScreenSize(int width, int height);
@@ -828,6 +833,66 @@ void tst_QWidget::fontPropagation3()
QCOMPARE(p.font().pointSize(), child->font().pointSize());
}
+/*!
+ This tests that children that are added to a widget with an explicitly
+ defined font inherit that font correctly, merging (and overriding)
+ with the font that might be defined by the platform theme.
+*/
+void tst_QWidget::fontPropagationDynamic()
+{
+ // override side effects from previous tests
+ QFont themedFont;
+ themedFont.setBold(true);
+ themedFont.setPointSize(42);
+ QApplication::setFont(themedFont, "QPropagationTestWidget");
+
+ QWidget parent;
+ QWidget firstChild(&parent);
+
+ const QFont defaultFont = parent.font();
+ QFont appFont = defaultFont;
+ appFont.setPointSize(72);
+
+ // sanity check
+ QVERIFY(themedFont != defaultFont);
+ QVERIFY(themedFont != appFont);
+
+ // palette propagates to existing children
+ parent.setFont(appFont);
+ QCOMPARE(firstChild.font().pointSize(), appFont.pointSize());
+
+ // palatte propagates to children added later
+ QWidget secondChild(&parent);
+ QCOMPARE(secondChild.font().pointSize(), appFont.pointSize());
+ QWidget thirdChild;
+ QCOMPARE(thirdChild.font().pointSize(), defaultFont.pointSize());
+ thirdChild.setParent(&parent);
+ QCOMPARE(thirdChild.font().pointSize(), appFont.pointSize());
+
+ // even if the child has an override in QApplication::font
+ QPropagationTestWidget themedChild;
+ themedChild.ensurePolished(); // needed for default font to be set up
+ QCOMPARE(themedChild.font().pointSize(), themedFont.pointSize());
+ QCOMPARE(themedChild.font().bold(), themedFont.bold());
+ themedChild.setParent(&parent);
+ QCOMPARE(themedChild.font().pointSize(), appFont.pointSize());
+ QCOMPARE(themedChild.font().bold(), themedFont.bold());
+
+ // grand children as well
+ QPropagationTestWidget themedGrandChild;
+ themedGrandChild.setParent(&themedChild);
+ QCOMPARE(themedGrandChild.font().pointSize(), appFont.pointSize());
+ QCOMPARE(themedGrandChild.font().bold(), themedFont.bold());
+
+ // child with own font attribute does not inherit from parent
+ QFont childFont = defaultFont;
+ childFont.setPointSize(9);
+ QWidget modifiedChild;
+ modifiedChild.setFont(childFont);
+ modifiedChild.setParent(&parent);
+ QCOMPARE(modifiedChild.font().pointSize(), childFont.pointSize());
+}
+
void tst_QWidget::palettePropagation()
{
QScopedPointer<QWidget> testWidget(new QWidget);
@@ -872,8 +937,8 @@ void tst_QWidget::palettePropagation2()
// ! Note, the code below is executed in tst_QWidget's constructor.
// QPalette palette;
- // font.setColor(QPalette::ToolTipBase, QColor(12, 13, 14));
- // font.setColor(QPalette::Text, QColor(21, 22, 23));
+ // palette.setColor(QPalette::ToolTipBase, QColor(12, 13, 14));
+ // palette.setColor(QPalette::Text, QColor(21, 22, 23));
// qApp->setPalette(palette, "QPropagationTestWidget");
QScopedPointer<QWidget> root(new QWidget);
@@ -972,6 +1037,68 @@ void tst_QWidget::palettePropagation2()
QCOMPARE(child5->palette().color(QPalette::ToolTipText), sysPalButton);
}
+/*!
+ This tests that children that are added to a widget with an explicitly
+ defined palette inherit that palette correctly, merging (and overriding)
+ with the palette that might be defined by the platform theme.
+*/
+void tst_QWidget::palettePropagationDynamic()
+{
+ // override side effects from previous tests
+ QPalette themedPalette;
+ themedPalette.setColor(QPalette::ToolTipBase, QColor(12, 13, 14));
+ themedPalette.setColor(QPalette::Text, QColor(21, 22, 23));
+ QApplication::setPalette(themedPalette, "QPropagationTestWidget");
+
+ QWidget parent;
+ QWidget firstChild(&parent);
+
+ const QPalette defaultPalette = parent.palette();
+ QPalette appPalette = defaultPalette;
+ const QColor appColor(1, 2, 3);
+ appPalette.setColor(QPalette::Text, appColor);
+
+ // sanity check
+ QVERIFY(themedPalette != defaultPalette);
+ QVERIFY(themedPalette != appPalette);
+
+ // palette propagates to existing children
+ parent.setPalette(appPalette);
+ QCOMPARE(firstChild.palette().color(QPalette::Text), appPalette.color(QPalette::Text));
+
+ // palatte propagates to children added later
+ QWidget secondChild(&parent);
+ QCOMPARE(secondChild.palette().color(QPalette::Text), appPalette.color(QPalette::Text));
+ QWidget thirdChild;
+ QCOMPARE(thirdChild.palette().color(QPalette::Text), defaultPalette.color(QPalette::Text));
+ thirdChild.setParent(&parent);
+ QCOMPARE(thirdChild.palette().color(QPalette::Text), appPalette.color(QPalette::Text));
+
+ // even if the child has an override in QApplication::palette
+ QPropagationTestWidget themedChild;
+ themedChild.ensurePolished(); // needed for default palette to be set up
+ QCOMPARE(themedChild.palette().color(QPalette::Text), themedPalette.color(QPalette::Text));
+ QCOMPARE(themedChild.palette().color(QPalette::ToolTipBase), themedPalette.color(QPalette::ToolTipBase));
+ themedChild.setParent(&parent);
+ QCOMPARE(themedChild.palette().color(QPalette::Text), appPalette.color(QPalette::Text));
+ QCOMPARE(themedChild.palette().color(QPalette::ToolTipBase), themedPalette.color(QPalette::ToolTipBase));
+
+ // grand children as well
+ QPropagationTestWidget themedGrandChild;
+ themedGrandChild.setParent(&themedChild);
+ QCOMPARE(themedGrandChild.palette().color(QPalette::Text), appPalette.color(QPalette::Text));
+ QCOMPARE(themedGrandChild.palette().color(QPalette::ToolTipBase), themedPalette.color(QPalette::ToolTipBase));
+
+ // child with own color does not inherit from parent
+ QPalette childPalette = defaultPalette;
+ childPalette.setColor(QPalette::Text, Qt::red);
+ QWidget modifiedChild;
+ modifiedChild.setPalette(childPalette);
+ modifiedChild.setParent(&parent);
+ QCOMPARE(modifiedChild.palette().color(QPalette::Text), childPalette.color(QPalette::Text));
+
+}
+
void tst_QWidget::enabledPropagation()
{
QScopedPointer<QWidget> testWidget(new QWidget);
@@ -8210,6 +8337,40 @@ void tst_QWidget::alienWidgets()
}
}
+using WidgetAttributes = QVector<Qt::WidgetAttribute>;
+
+void tst_QWidget::nativeWindowPosition_data()
+{
+ QTest::addColumn<WidgetAttributes>("attributes");
+
+ QTest::newRow("non-native all the way")
+ << WidgetAttributes{};
+ QTest::newRow("native all the way")
+ << WidgetAttributes{ Qt::WA_NativeWindow };
+ QTest::newRow("native with non-native ancestor")
+ << WidgetAttributes{ Qt::WA_NativeWindow, Qt::WA_DontCreateNativeAncestors };
+}
+
+void tst_QWidget::nativeWindowPosition()
+{
+ QWidget topLevel;
+ QWidget child(&topLevel);
+ child.move(5, 5);
+
+ QWidget grandChild(&child);
+ grandChild.move(10, 10);
+
+ QFETCH(WidgetAttributes, attributes);
+ for (auto attribute : attributes)
+ grandChild.setAttribute(attribute);
+
+ topLevel.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&topLevel));
+
+ QCOMPARE(child.pos(), QPoint(5, 5));
+ QCOMPARE(grandChild.pos(), QPoint(10, 10));
+}
+
class ASWidget : public QWidget
{
public:
@@ -11360,5 +11521,55 @@ void tst_QWidget::winIdAfterClose()
delete spy;
}
+class LanguageChangeEventWidget : public QWidget
+{
+public:
+ LanguageChangeEventWidget(QWidget *parent = nullptr) : QWidget(parent) {}
+ int languageChangeCount = 0;
+protected:
+ bool event(QEvent *e) override
+ {
+ if (e->type() == QEvent::LanguageChange)
+ languageChangeCount++;
+ return QWidget::event(e);
+ }
+};
+
+class LanguageChangeEventWindow : public QWindow
+{
+public:
+ LanguageChangeEventWindow(QWindow *parent = nullptr) : QWindow(parent) {}
+ int languageChangeCount = 0;
+protected:
+ bool event(QEvent *e) override
+ {
+ if (e->type() == QEvent::LanguageChange)
+ languageChangeCount++;
+ return QWindow::event(e);
+ }
+};
+
+void tst_QWidget::receivesLanguageChangeEvent()
+{
+ // Confirm that any QWindow or QWidget only gets a single
+ // LanguageChange event when a translator is installed
+ LanguageChangeEventWidget topLevel;
+ auto childWidget = new LanguageChangeEventWidget(&topLevel);
+ topLevel.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&topLevel));
+ LanguageChangeEventWindow ww;
+ ww.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&ww));
+ LanguageChangeEventWidget topLevelNotShown;
+ QTranslator t;
+ QVERIFY(t.load("hellotr_la.qm", ":/"));
+ QVERIFY(qApp->installTranslator(&t));
+ QCoreApplication::sendPostedEvents(0, QEvent::LanguageChange);
+ QCOMPARE(topLevel.languageChangeCount, 1);
+ QCOMPARE(topLevelNotShown.languageChangeCount, 1);
+ QCOMPARE(childWidget->languageChangeCount, 1);
+ QCOMPARE(ww.languageChangeCount, 1);
+}
+
QTEST_MAIN(tst_QWidget)
#include "tst_qwidget.moc"
diff --git a/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp b/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp
index dd3e2f844b..f42e2d777b 100644
--- a/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp
+++ b/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp
@@ -968,6 +968,7 @@ void tst_QWidget_window::tst_resize_count()
{
{
ResizeWidget resize;
+ resize.setWindowFlags(Qt::X11BypassWindowManagerHint);
resize.show();
QVERIFY(QTest::qWaitForWindowExposed(&resize));
#ifdef Q_OS_WINRT
@@ -1000,6 +1001,7 @@ void tst_QWidget_window::tst_resize_count()
}
{
ResizeWidget parent;
+ parent.setWindowFlag(Qt::X11BypassWindowManagerHint);
ResizeWidget child(&parent);
child.resize(m_testWidgetSize);
child.winId();
diff --git a/tests/libfuzzer/gui/text/qtextdocument/setHtml/main.cpp b/tests/libfuzzer/gui/text/qtextdocument/sethtml/main.cpp
index 51fa3c9e0f..51fa3c9e0f 100644
--- a/tests/libfuzzer/gui/text/qtextdocument/setHtml/main.cpp
+++ b/tests/libfuzzer/gui/text/qtextdocument/sethtml/main.cpp
diff --git a/tests/libfuzzer/gui/text/qtextdocument/setHtml/setHtml.pro b/tests/libfuzzer/gui/text/qtextdocument/sethtml/sethtml.pro
index af5ef9e940..af5ef9e940 100644
--- a/tests/libfuzzer/gui/text/qtextdocument/setHtml/setHtml.pro
+++ b/tests/libfuzzer/gui/text/qtextdocument/sethtml/sethtml.pro
diff --git a/tests/libfuzzer/gui/text/qtextdocument/setMarkdown/main.cpp b/tests/libfuzzer/gui/text/qtextdocument/setmarkdown/main.cpp
index 66ddf738f2..66ddf738f2 100644
--- a/tests/libfuzzer/gui/text/qtextdocument/setMarkdown/main.cpp
+++ b/tests/libfuzzer/gui/text/qtextdocument/setmarkdown/main.cpp
diff --git a/tests/libfuzzer/gui/text/qtextdocument/setMarkdown/setMarkdown.pro b/tests/libfuzzer/gui/text/qtextdocument/setmarkdown/setmarkdown.pro
index 758622e1af..758622e1af 100644
--- a/tests/libfuzzer/gui/text/qtextdocument/setMarkdown/setMarkdown.pro
+++ b/tests/libfuzzer/gui/text/qtextdocument/setmarkdown/setmarkdown.pro
diff --git a/tests/libfuzzer/gui/text/qtextlayout/beginLayout/beginLayout.pro b/tests/libfuzzer/gui/text/qtextlayout/beginlayout/beginlayout.pro
index af5ef9e940..af5ef9e940 100644
--- a/tests/libfuzzer/gui/text/qtextlayout/beginLayout/beginLayout.pro
+++ b/tests/libfuzzer/gui/text/qtextlayout/beginlayout/beginlayout.pro
diff --git a/tests/libfuzzer/gui/text/qtextlayout/beginLayout/main.cpp b/tests/libfuzzer/gui/text/qtextlayout/beginlayout/main.cpp
index dfb9559241..dfb9559241 100644
--- a/tests/libfuzzer/gui/text/qtextlayout/beginLayout/main.cpp
+++ b/tests/libfuzzer/gui/text/qtextlayout/beginlayout/main.cpp
diff --git a/tests/manual/rhi/hellominimalcrossgfxtriangle/window.cpp b/tests/manual/rhi/hellominimalcrossgfxtriangle/window.cpp
index f3f00e0255..fc7bdff3de 100644
--- a/tests/manual/rhi/hellominimalcrossgfxtriangle/window.cpp
+++ b/tests/manual/rhi/hellominimalcrossgfxtriangle/window.cpp
@@ -167,7 +167,7 @@ void Window::init()
#if defined(Q_OS_MACOS) || defined(Q_OS_IOS)
if (m_graphicsApi == QRhi::Metal) {
QRhiMetalInitParams params;
- m_rhi = QRhi::create(QRhi::Metal, &params, rhiFlags);
+ m_rhi.reset(QRhi::create(QRhi::Metal, &params, rhiFlags));
}
#endif