From 5b24d3dd3559826dfa3cac38be525a052003e2a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Thu, 13 Jul 2017 08:50:18 +0200 Subject: [PATCH 01/27] Add missing constexpr specifier to two iterators The classes themselves and their equality operators are used in constexpr functions/ctors (in QKeyValueIterator) so Visual Studio 2017 expects them to be marked constexpr as well. Currently this causes a compilation error when instantiating a QKeyValueIterator using either of these iterators. Change-Id: I2e3eeaf3b3f11f381a63875e6575dfd82fe56fcb Reviewed-by: Edward Welbourne Reviewed-by: Thiago Macieira --- src/corelib/tools/qhash.h | 6 +++--- src/corelib/tools/qmap.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h index b2c3cf574d1..035ec57957d 100644 --- a/src/corelib/tools/qhash.h +++ b/src/corelib/tools/qhash.h @@ -373,7 +373,7 @@ public: typedef const T *pointer; typedef const T &reference; - inline const_iterator() : i(Q_NULLPTR) { } + Q_DECL_CONSTEXPR inline const_iterator() : i(Q_NULLPTR) { } explicit inline const_iterator(void *node) : i(reinterpret_cast(node)) { } #ifdef QT_STRICT_ITERATORS @@ -387,8 +387,8 @@ public: inline const T &value() const { return concrete(i)->value; } inline const T &operator*() const { return concrete(i)->value; } inline const T *operator->() const { return &concrete(i)->value; } - inline bool operator==(const const_iterator &o) const { return i == o.i; } - inline bool operator!=(const const_iterator &o) const { return i != o.i; } + Q_DECL_CONSTEXPR inline bool operator==(const const_iterator &o) const { return i == o.i; } + Q_DECL_CONSTEXPR inline bool operator!=(const const_iterator &o) const { return i != o.i; } inline const_iterator &operator++() { i = QHashData::nextNode(i); diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h index a3b11eddcf9..37ed24000d3 100644 --- a/src/corelib/tools/qmap.h +++ b/src/corelib/tools/qmap.h @@ -473,7 +473,7 @@ public: typedef const T *pointer; typedef const T &reference; - inline const_iterator() : i(Q_NULLPTR) { } + Q_DECL_CONSTEXPR inline const_iterator() : i(Q_NULLPTR) { } inline const_iterator(const Node *node) : i(node) { } #ifdef QT_STRICT_ITERATORS explicit inline const_iterator(const iterator &o) @@ -486,8 +486,8 @@ public: inline const T &value() const { return i->value; } inline const T &operator*() const { return i->value; } inline const T *operator->() const { return &i->value; } - inline bool operator==(const const_iterator &o) const { return i == o.i; } - inline bool operator!=(const const_iterator &o) const { return i != o.i; } + Q_DECL_CONSTEXPR inline bool operator==(const const_iterator &o) const { return i == o.i; } + Q_DECL_CONSTEXPR inline bool operator!=(const const_iterator &o) const { return i != o.i; } inline const_iterator &operator++() { i = i->nextNode(); From dbcfe31892c7c57658482de965d6203914b2feea Mon Sep 17 00:00:00 2001 From: Alex Blasche Date: Wed, 12 Jul 2017 12:39:09 +0200 Subject: [PATCH 02/27] Fix empty "Command line was" string in generated source files Task-number: QTBUG-61370 Change-Id: If829a889acfe092adad4ac443d71e63b67ba7f55 Reviewed-by: Kai Koehne Reviewed-by: Thiago Macieira --- src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp b/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp index 9ccf8be73a9..177cbbeb719 100644 --- a/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp +++ b/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp @@ -1134,6 +1134,11 @@ int main(int argc, char **argv) QDBusIntrospection::Interfaces interfaces = readInput(); cleanInterfaces(interfaces); + QStringList args = app.arguments(); + args.removeFirst(); + commandLine = QLatin1String(PROGRAMNAME " "); + commandLine += args.join(QLatin1Char(' ')); + if (!proxyFile.isEmpty() || adaptorFile.isEmpty()) writeProxy(proxyFile, interfaces); From d4700b2317ea8d97c9c1a1d6649d83e5aee0f80f Mon Sep 17 00:00:00 2001 From: Alex Blasche Date: Wed, 12 Jul 2017 12:47:52 +0200 Subject: [PATCH 03/27] Bump copyright year of qdbuscpp2xml and qdbusxml2cpp to 2017 Change-Id: I7be6f45d359db813b15a3754b3ed203cb829a3d0 Reviewed-by: Kai Koehne --- src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp | 2 +- src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp b/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp index 7ddd0fcf5dd..c76983200e1 100644 --- a/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp +++ b/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp @@ -62,7 +62,7 @@ static const char docTypeHeader[] = #define PROGRAMNAME "qdbuscpp2xml" #define PROGRAMVERSION "0.2" -#define PROGRAMCOPYRIGHT "Copyright (C) 2016 The Qt Company Ltd." +#define PROGRAMCOPYRIGHT "Copyright (C) 2017 The Qt Company Ltd." static QString outputFile; static int flags; diff --git a/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp b/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp index 177cbbeb719..bbe738dadb0 100644 --- a/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp +++ b/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp @@ -46,7 +46,7 @@ #define PROGRAMNAME "qdbusxml2cpp" #define PROGRAMVERSION "0.8" -#define PROGRAMCOPYRIGHT "Copyright (C) 2016 The Qt Company Ltd." +#define PROGRAMCOPYRIGHT "Copyright (C) 2017 The Qt Company Ltd." #define ANNOTATION_NO_WAIT "org.freedesktop.DBus.Method.NoReply" From dc81a99decace7cdf47136731f9bb3ef35274a9e Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 3 Jul 2017 13:56:14 +0200 Subject: [PATCH 04/27] Examples: Remove remains of wince MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-52590 Task-number: QTBUG-60628 Task-number: QTBUG-60633 Task-number: QTBUG-60635 Task-number: QTBUG-60641 Task-number: QTBUG-60659 Change-Id: I9ffc3e25893d2281b19cc12b70e1a92fb2a8b708 Reviewed-by: Topi Reiniö --- examples/embedded/embedded.pro | 2 +- .../multistreamserver/multistreamserver.pro | 6 ------ examples/opengl/opengl.pro | 14 ++++++-------- examples/qtconcurrent/qtconcurrent.pro | 4 +--- examples/sql/books/books.pro | 8 -------- examples/sql/sql.pro | 12 +++++------- .../widgets/dialogs/configdialog/configdialog.pro | 2 -- examples/widgets/dialogs/dialogs.pro | 10 +++------- .../dialogs/standarddialogs/standarddialogs.pro | 2 -- examples/widgets/dialogs/tabdialog/tabdialog.pro | 2 -- examples/xml/dombookmarks/dombookmarks.pro | 7 ------- examples/xml/htmlinfo/htmlinfo.pro | 6 ------ examples/xml/saxbookmarks/saxbookmarks.pro | 6 ------ 13 files changed, 16 insertions(+), 65 deletions(-) diff --git a/examples/embedded/embedded.pro b/examples/embedded/embedded.pro index 90ee504adf7..e772eb88aab 100644 --- a/examples/embedded/embedded.pro +++ b/examples/embedded/embedded.pro @@ -1,4 +1,4 @@ -requires(if(wince|embedded|x11):qtHaveModule(gui)) +requires(if(embedded|x11):qtHaveModule(gui)) TEMPLATE = subdirs SUBDIRS = styleexample raycasting flickable digiflip diff --git a/examples/network/multistreamserver/multistreamserver.pro b/examples/network/multistreamserver/multistreamserver.pro index 75a7e6bbecc..38301e122e9 100644 --- a/examples/network/multistreamserver/multistreamserver.pro +++ b/examples/network/multistreamserver/multistreamserver.pro @@ -16,9 +16,3 @@ EXAMPLE_FILES = animation.gif # install target.path = $$[QT_INSTALL_EXAMPLES]/network/multistreamserver INSTALLS += target - -wince*: { - addFiles.files += *.gif - addFiles.path = . - DEPLOYMENT += addFiles -} diff --git a/examples/opengl/opengl.pro b/examples/opengl/opengl.pro index ef44201494b..89b3e1d86e0 100644 --- a/examples/opengl/opengl.pro +++ b/examples/opengl/opengl.pro @@ -8,14 +8,12 @@ qtHaveModule(widgets) { SUBDIRS += contextinfo \ threadedqopenglwidget \ 2dpainting \ - hellogl2 - - !wince: SUBDIRS += \ - qopenglwidget \ - cube \ - textures \ - hellogles3 \ - computegles31 + hellogl2 \ + qopenglwidget \ + cube \ + textures \ + hellogles3 \ + computegles31 } EXAMPLE_FILES += \ diff --git a/examples/qtconcurrent/qtconcurrent.pro b/examples/qtconcurrent/qtconcurrent.pro index 6e4e5f0f162..bdf41b03ea1 100644 --- a/examples/qtconcurrent/qtconcurrent.pro +++ b/examples/qtconcurrent/qtconcurrent.pro @@ -3,12 +3,10 @@ requires(qtHaveModule(concurrent)) TEMPLATE = subdirs SUBDIRS = imagescaling \ map \ + progressdialog \ runfunction \ wordcount -!wince* { - SUBDIRS += progressdialog -} !qtHaveModule(gui) { SUBDIRS -= \ diff --git a/examples/sql/books/books.pro b/examples/sql/books/books.pro index c64766c29f3..2b3d541fe88 100644 --- a/examples/sql/books/books.pro +++ b/examples/sql/books/books.pro @@ -10,11 +10,3 @@ QT += sql widgets widgets target.path = $$[QT_INSTALL_EXAMPLES]/sql/books INSTALLS += target - - -wince { - CONFIG(debug, debug|release):sqlPlugins.files = $$QT_BUILD_TREE/plugins/sqldrivers/*d4.dll - CONFIG(release, debug|release):sqlPlugins.files = $$QT_BUILD_TREE/plugins/sqldrivers/*[^d]4.dll - sqlPlugins.path = sqldrivers - INSTALLS += sqlPlugins -} diff --git a/examples/sql/sql.pro b/examples/sql/sql.pro index 135d05b4e29..a427e109295 100644 --- a/examples/sql/sql.pro +++ b/examples/sql/sql.pro @@ -4,16 +4,14 @@ TEMPLATE = subdirs SUBDIRS = books \ drilldown \ - cachedtable \ - relationaltablemodel \ - sqlwidgetmapper - -!wince:qtHaveModule(xml): SUBDIRS += masterdetail - -!wince: SUBDIRS += \ + cachedtable \ querymodel \ + relationaltablemodel \ + sqlwidgetmapper \ tablemodel +qtHaveModule(xml): SUBDIRS += masterdetail + !cross_compile:{ contains(QT_BUILD_PARTS, tools):{ SUBDIRS += sqlbrowser diff --git a/examples/widgets/dialogs/configdialog/configdialog.pro b/examples/widgets/dialogs/configdialog/configdialog.pro index e99fce13acc..8ba55becadd 100644 --- a/examples/widgets/dialogs/configdialog/configdialog.pro +++ b/examples/widgets/dialogs/configdialog/configdialog.pro @@ -10,5 +10,3 @@ RESOURCES += configdialog.qrc # install target.path = $$[QT_INSTALL_EXAMPLES]/widgets/dialogs/configdialog INSTALLS += target - -wince50standard-x86-msvc2005: LIBS += libcmt.lib corelibc.lib ole32.lib oleaut32.lib uuid.lib commctrl.lib coredll.lib winsock.lib ws2.lib diff --git a/examples/widgets/dialogs/dialogs.pro b/examples/widgets/dialogs/dialogs.pro index 6f193094407..82e814dcb03 100644 --- a/examples/widgets/dialogs/dialogs.pro +++ b/examples/widgets/dialogs/dialogs.pro @@ -3,17 +3,13 @@ QT_FOR_CONFIG += widgets TEMPLATE = subdirs SUBDIRS = classwizard \ configdialog \ + extension \ + findfiles \ + licensewizard \ standarddialogs \ tabdialog \ trivialwizard -!wince { - SUBDIRS += \ - licensewizard \ - extension \ - findfiles -} - !qtHaveModule(printsupport): SUBDIRS -= licensewizard !qtConfig(wizard) { SUBDIRS -= trivialwizard licensewizard classwizard diff --git a/examples/widgets/dialogs/standarddialogs/standarddialogs.pro b/examples/widgets/dialogs/standarddialogs/standarddialogs.pro index 12a814cb691..d2e9e197715 100644 --- a/examples/widgets/dialogs/standarddialogs/standarddialogs.pro +++ b/examples/widgets/dialogs/standarddialogs/standarddialogs.pro @@ -7,5 +7,3 @@ SOURCES = dialog.cpp \ # install target.path = $$[QT_INSTALL_EXAMPLES]/widgets/dialogs/standarddialogs INSTALLS += target - -wince50standard-x86-msvc2005: LIBS += libcmt.lib corelibc.lib ole32.lib oleaut32.lib uuid.lib commctrl.lib coredll.lib winsock.lib ws2.lib diff --git a/examples/widgets/dialogs/tabdialog/tabdialog.pro b/examples/widgets/dialogs/tabdialog/tabdialog.pro index c282505ac13..8a686b4f5ca 100644 --- a/examples/widgets/dialogs/tabdialog/tabdialog.pro +++ b/examples/widgets/dialogs/tabdialog/tabdialog.pro @@ -7,5 +7,3 @@ SOURCES = main.cpp \ # install target.path = $$[QT_INSTALL_EXAMPLES]/widgets/dialogs/tabdialog INSTALLS += target - -wince50standard-x86-msvc2005: LIBS += libcmt.lib corelibc.lib ole32.lib oleaut32.lib uuid.lib commctrl.lib coredll.lib winsock.lib ws2.lib diff --git a/examples/xml/dombookmarks/dombookmarks.pro b/examples/xml/dombookmarks/dombookmarks.pro index 0ab4f0266d6..07004377a0b 100644 --- a/examples/xml/dombookmarks/dombookmarks.pro +++ b/examples/xml/dombookmarks/dombookmarks.pro @@ -10,10 +10,3 @@ EXAMPLE_FILES = frank.xbel jennifer.xbel # install target.path = $$[QT_INSTALL_EXAMPLES]/xml/dombookmarks INSTALLS += target - -wince { - addFiles.files = frank.xbel jennifer.xbel - addFiles.path = "\\My Documents" - INSTALLS += addFiles -} - diff --git a/examples/xml/htmlinfo/htmlinfo.pro b/examples/xml/htmlinfo/htmlinfo.pro index 8adaa780b8f..e106c69b522 100644 --- a/examples/xml/htmlinfo/htmlinfo.pro +++ b/examples/xml/htmlinfo/htmlinfo.pro @@ -6,12 +6,6 @@ RESOURCES = resources.qrc win32: CONFIG += console -wince { - htmlfiles.files = *.html - htmlfiles.path = . - INSTALLS += htmlfiles -} - # install target.path = $$[QT_INSTALL_EXAMPLES]/xml/htmlinfo INSTALLS += target diff --git a/examples/xml/saxbookmarks/saxbookmarks.pro b/examples/xml/saxbookmarks/saxbookmarks.pro index 96a48ef5d40..d07a6e3fb83 100644 --- a/examples/xml/saxbookmarks/saxbookmarks.pro +++ b/examples/xml/saxbookmarks/saxbookmarks.pro @@ -12,9 +12,3 @@ EXAMPLE_FILES = frank.xbel jennifer.xbel # install target.path = $$[QT_INSTALL_EXAMPLES]/xml/saxbookmarks INSTALLS += target - -wince { - addFiles.files = frank.xbel jennifer.xbel - addFiles.path = "\\My Documents" - INSTALLS += addFiles -} From 4db3a5f8ebc8031da12d903807a7b2857e28276a Mon Sep 17 00:00:00 2001 From: Stephan Binner Date: Thu, 13 Jul 2017 13:08:02 +0200 Subject: [PATCH 05/27] Add missing #include for -no-widgets Task-number: QTBUG-61780 Change-Id: I62fccc6474965278cb1b258b512fda3b60f995f3 Reviewed-by: Oswald Buddenhagen --- src/plugins/platforms/cocoa/qcocoatheme.mm | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/platforms/cocoa/qcocoatheme.mm b/src/plugins/platforms/cocoa/qcocoatheme.mm index 2f4a1e3e4c5..a1c1b379f74 100644 --- a/src/plugins/platforms/cocoa/qcocoatheme.mm +++ b/src/plugins/platforms/cocoa/qcocoatheme.mm @@ -57,6 +57,7 @@ #include #include #include +#include #include #include From a23568be6c6859b3a149cfadb1104da4f32318f5 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Mon, 10 Jul 2017 16:34:50 +0200 Subject: [PATCH 06/27] Fix CONFIG+=silent for MSVC non-inference rules silent.prf modifies the compiler commands by prefixing them with a silencing echo command. For MSVC, the used $< syntax is only valid in inference rules. However, the PCH rule is not an inference rule and breaks when silent.prf is used. Remove the echo command for MSVC. The compiler already outputs the currently compiled file. There's no need to do it twice. Task-number: QTBUG-61688 Change-Id: I7e2c1211e471c9c149c16cac8e87406e88ee2d97 Reviewed-by: Thiago Macieira Reviewed-by: Oswald Buddenhagen --- mkspecs/features/silent.prf | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/mkspecs/features/silent.prf b/mkspecs/features/silent.prf index 141e6bf9e40..6d7c170419a 100644 --- a/mkspecs/features/silent.prf +++ b/mkspecs/features/silent.prf @@ -1,6 +1,11 @@ !macx-xcode { - QMAKE_CC = @echo compiling $< && $$QMAKE_CC - QMAKE_CXX = @echo compiling $< && $$QMAKE_CXX + msvc { + QMAKE_CC = @$$QMAKE_CC + QMAKE_CXX = @$$QMAKE_CXX + } else { + QMAKE_CC = @echo compiling $< && $$QMAKE_CC + QMAKE_CXX = @echo compiling $< && $$QMAKE_CXX + } !contains(QMAKE_LINK, "@:"):QMAKE_LINK = @echo linking $@ && $$QMAKE_LINK QMAKE_LINK_SHLIB = @echo linking $@ && $$QMAKE_LINK_SHLIB } From 773178900f39febb0509cb4170bc091c9f91d3b3 Mon Sep 17 00:00:00 2001 From: Stephan Binner Date: Sun, 9 Jul 2017 16:55:03 +0200 Subject: [PATCH 07/27] Convert features.treeview to QT_[REQUIRE_]CONFIG Change-Id: I4a036a0410615ac563b17f7715c47acccb8abfca Reviewed-by: Oswald Buddenhagen --- src/widgets/accessible/complexwidgets.cpp | 1 - src/widgets/accessible/itemviews.cpp | 21 +++++++++++-------- src/widgets/accessible/itemviews_p.h | 6 +++--- .../accessible/qaccessiblewidgetfactory.cpp | 6 ++++-- src/widgets/itemviews/itemviews.pri | 11 +++++++--- src/widgets/itemviews/qabstractitemview.cpp | 1 - src/widgets/itemviews/qtreeview.cpp | 3 --- src/widgets/itemviews/qtreeview.h | 7 ++----- src/widgets/itemviews/qtreeview_p.h | 4 +--- src/widgets/styles/qcommonstyle.cpp | 5 ++++- src/widgets/styles/qmacstyle_mac.mm | 6 ++++-- src/widgets/styles/qmacstyle_mac_p_p.h | 2 ++ src/widgets/styles/qpixmapstyle.cpp | 1 - src/widgets/styles/qwindowsvistastyle_p_p.h | 2 ++ src/widgets/util/qcompleter_p.h | 2 +- src/widgets/widgets/qcombobox.cpp | 6 ++++-- 16 files changed, 47 insertions(+), 37 deletions(-) diff --git a/src/widgets/accessible/complexwidgets.cpp b/src/widgets/accessible/complexwidgets.cpp index dd9bea1aec0..50aba759c34 100644 --- a/src/widgets/accessible/complexwidgets.cpp +++ b/src/widgets/accessible/complexwidgets.cpp @@ -53,7 +53,6 @@ #if QT_CONFIG(whatsthis) #include #endif -#include #include #include #include diff --git a/src/widgets/accessible/itemviews.cpp b/src/widgets/accessible/itemviews.cpp index 87c0a595634..4d1a4589eef 100644 --- a/src/widgets/accessible/itemviews.cpp +++ b/src/widgets/accessible/itemviews.cpp @@ -44,8 +44,11 @@ #include #endif #include +#if QT_CONFIG(treeview) #include #include +#endif +#include #ifndef QT_NO_ACCESSIBILITY @@ -88,7 +91,7 @@ QAccessibleTable::QAccessibleTable(QWidget *w) m_role = QAccessible::Table; } else #endif -#ifndef QT_NO_TREEVIEW +#if QT_CONFIG(treeview) if (qobject_cast(view())) { m_role = QAccessible::Tree; } else @@ -123,7 +126,7 @@ QHeaderView *QAccessibleTable::horizontalHeader() const } else if (const QTableView *tv = qobject_cast(view())) { header = tv->horizontalHeader(); #endif -#ifndef QT_NO_TREEVIEW +#if QT_CONFIG(treeview) } else if (const QTreeView *tv = qobject_cast(view())) { header = tv->header(); #endif @@ -647,7 +650,7 @@ void QAccessibleTable::modelChange(QAccessibleTableModelChangeEvent *event) } } -#ifndef QT_NO_TREEVIEW +#if QT_CONFIG(treeview) // TREE VIEW @@ -820,7 +823,7 @@ bool QAccessibleTree::selectRow(int row) return true; } -#endif // QT_NO_TREEVIEW +#endif // QT_CONFIG(treeview) // TABLE CELL @@ -872,7 +875,7 @@ QHeaderView *QAccessibleTableCell::horizontalHeader() const } else if (const QTableView *tv = qobject_cast(view)) { header = tv->horizontalHeader(); #endif -#ifndef QT_NO_TREEVIEW +#if QT_CONFIG(treeview) } else if (const QTreeView *tv = qobject_cast(view)) { header = tv->header(); #endif @@ -898,7 +901,7 @@ int QAccessibleTableCell::columnIndex() const int QAccessibleTableCell::rowIndex() const { -#ifndef QT_NO_TREEVIEW +#if QT_CONFIG(treeview) if (role() == QAccessible::TreeItem) { const QTreeView *treeView = qobject_cast(view); Q_ASSERT(treeView); @@ -1034,7 +1037,7 @@ QAccessible::State QAccessibleTableCell::state() const if (view->selectionMode() == QAbstractItemView::ExtendedSelection) st.extSelectable = true; } -#ifndef QT_NO_TREEVIEW +#if QT_CONFIG(treeview) if (m_role == QAccessible::TreeItem) { const QTreeView *treeView = qobject_cast(view); if (treeView->model()->hasChildren(m_index)) @@ -1135,7 +1138,7 @@ QRect QAccessibleTableHeaderCell::rect() const header = tv->verticalHeader(); } #endif -#ifndef QT_NO_TREEVIEW +#if QT_CONFIG(treeview) } else if (const QTreeView *tv = qobject_cast(view)) { header = tv->header(); #endif @@ -1202,7 +1205,7 @@ QHeaderView *QAccessibleTableHeaderCell::headerView() const header = tv->verticalHeader(); } #endif -#ifndef QT_NO_TREEVIEW +#if QT_CONFIG(treeview) } else if (const QTreeView *tv = qobject_cast(view)) { header = tv->header(); #endif diff --git a/src/widgets/accessible/itemviews_p.h b/src/widgets/accessible/itemviews_p.h index 1b3869f2fac..9542a569db8 100644 --- a/src/widgets/accessible/itemviews_p.h +++ b/src/widgets/accessible/itemviews_p.h @@ -145,7 +145,7 @@ private: QAccessible::Role m_role; }; -#ifndef QT_NO_TREEVIEW +#if QT_CONFIG(treeview) class QAccessibleTree :public QAccessibleTable { public: @@ -223,7 +223,7 @@ private: void unselectCell(); friend class QAccessibleTable; -#ifndef QT_NO_TREEVIEW +#if QT_CONFIG(treeview) friend class QAccessibleTree; #endif }; @@ -259,7 +259,7 @@ private: Qt::Orientation orientation; friend class QAccessibleTable; -#ifndef QT_NO_TREEVIEW +#if QT_CONFIG(treeview) friend class QAccessibleTree; #endif }; diff --git a/src/widgets/accessible/qaccessiblewidgetfactory.cpp b/src/widgets/accessible/qaccessiblewidgetfactory.cpp index ccd176cd044..a39674dc7ac 100644 --- a/src/widgets/accessible/qaccessiblewidgetfactory.cpp +++ b/src/widgets/accessible/qaccessiblewidgetfactory.cpp @@ -46,7 +46,9 @@ #include "itemviews_p.h" #include +#if QT_CONFIG(treeview) #include +#endif #include #include @@ -140,10 +142,10 @@ QAccessibleInterface *qAccessibleFactory(const QString &classname, QObject *obje } else if (classname == QLatin1String("QMenu")) { iface = new QAccessibleMenu(widget); #endif -#ifndef QT_NO_TREEVIEW +#if QT_CONFIG(treeview) } else if (classname == QLatin1String("QTreeView")) { iface = new QAccessibleTree(widget); -#endif // QT_NO_TREEVIEW +#endif // QT_CONFIG(treeview) #ifndef QT_NO_ITEMVIEWS } else if (classname == QLatin1String("QTableView") || classname == QLatin1String("QListView")) { iface = new QAccessibleTable(widget); diff --git a/src/widgets/itemviews/itemviews.pri b/src/widgets/itemviews/itemviews.pri index 4101be56310..c68aa590bc7 100644 --- a/src/widgets/itemviews/itemviews.pri +++ b/src/widgets/itemviews/itemviews.pri @@ -9,8 +9,6 @@ HEADERS += \ itemviews/qlistview.h \ itemviews/qlistview_p.h \ itemviews/qbsptree_p.h \ - itemviews/qtreeview.h \ - itemviews/qtreeview_p.h \ itemviews/qabstractitemdelegate.h \ itemviews/qabstractitemdelegate_p.h \ itemviews/qitemdelegate.h \ @@ -26,7 +24,6 @@ SOURCES += \ itemviews/qheaderview.cpp \ itemviews/qlistview.cpp \ itemviews/qbsptree.cpp \ - itemviews/qtreeview.cpp \ itemviews/qabstractitemdelegate.cpp \ itemviews/qitemdelegate.cpp \ itemviews/qdirmodel.cpp \ @@ -70,6 +67,14 @@ qtConfig(tablewidget) { SOURCES += itemviews/qtablewidget.cpp } +qtConfig(treeview) { + HEADERS += \ + itemviews/qtreeview.h \ + itemviews/qtreeview_p.h + + SOURCES += itemviews/qtreeview.cpp +} + qtConfig(treewidget) { HEADERS += \ itemviews/qtreewidget.h \ diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp index f96bafdb57d..396016c44d4 100644 --- a/src/widgets/itemviews/qabstractitemview.cpp +++ b/src/widgets/itemviews/qabstractitemview.cpp @@ -52,7 +52,6 @@ #include #include #include -#include #include #include #include diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp index c1647cc2f19..2abb1a9c14f 100644 --- a/src/widgets/itemviews/qtreeview.cpp +++ b/src/widgets/itemviews/qtreeview.cpp @@ -38,7 +38,6 @@ ****************************************************************************/ #include "qtreeview.h" -#ifndef QT_NO_TREEVIEW #include #include #include @@ -3996,5 +3995,3 @@ int QTreeView::visualIndex(const QModelIndex &index) const QT_END_NAMESPACE #include "moc_qtreeview.cpp" - -#endif // QT_NO_TREEVIEW diff --git a/src/widgets/itemviews/qtreeview.h b/src/widgets/itemviews/qtreeview.h index 3c7cbddfbb5..c32c127cd10 100644 --- a/src/widgets/itemviews/qtreeview.h +++ b/src/widgets/itemviews/qtreeview.h @@ -45,11 +45,10 @@ class tst_QTreeView; +QT_REQUIRE_CONFIG(treeview); + QT_BEGIN_NAMESPACE - -#ifndef QT_NO_TREEVIEW - class QTreeViewPrivate; class QHeaderView; @@ -237,8 +236,6 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_sortIndicatorChanged(int column, Qt::SortOrder order)) }; -#endif // QT_NO_TREEVIEW - QT_END_NAMESPACE #endif // QTREEVIEW_H diff --git a/src/widgets/itemviews/qtreeview_p.h b/src/widgets/itemviews/qtreeview_p.h index 63af41292ba..9a391ee88a2 100644 --- a/src/widgets/itemviews/qtreeview_p.h +++ b/src/widgets/itemviews/qtreeview_p.h @@ -57,7 +57,7 @@ #include #include -#ifndef QT_NO_TREEVIEW +QT_REQUIRE_CONFIG(treeview); QT_BEGIN_NAMESPACE @@ -272,6 +272,4 @@ public: QT_END_NAMESPACE -#endif // QT_NO_TREEVIEW - #endif // QTREEVIEW_P_H diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp index 56f9bfb3e7d..973e89b3ef8 100644 --- a/src/widgets/styles/qcommonstyle.cpp +++ b/src/widgets/styles/qcommonstyle.cpp @@ -41,6 +41,7 @@ #include "qcommonstyle_p.h" #include +#include #include #include #include @@ -71,7 +72,9 @@ #if QT_CONFIG(rubberband) #include #endif +#if QT_CONFIG(treeview) #include "qtreeview.h" +#endif #include #include #include @@ -5250,7 +5253,7 @@ int QCommonStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget break; #endif case SH_Widget_Animate: -#ifndef QT_NO_TREEVIEW +#if QT_CONFIG(treeview) if (qobject_cast(widget)) { ret = false; } else diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm index 8a6e32105a1..99526683dde 100644 --- a/src/widgets/styles/qmacstyle_mac.mm +++ b/src/widgets/styles/qmacstyle_mac.mm @@ -88,7 +88,9 @@ #include #include #include +#if QT_CONFIG(treeview) #include +#endif #if QT_CONFIG(tableview) #include #endif @@ -420,7 +422,7 @@ static int getControlSize(const QStyleOption *option, const QWidget *widget) } -#ifndef QT_NO_TREEVIEW +#if QT_CONFIG(treeview) static inline bool isTreeView(const QWidget *widget) { return (widget && widget->parentWidget() && @@ -899,7 +901,7 @@ static QSize qt_aqua_get_known_size(QStyle::ContentsType ct, const QWidget *widg break; #endif case QStyle::CT_HeaderSection: -#ifndef QT_NO_TREEVIEW +#if QT_CONFIG(treeview) if (isTreeView(widg)) ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricListHeaderHeight)); #endif diff --git a/src/widgets/styles/qmacstyle_mac_p_p.h b/src/widgets/styles/qmacstyle_mac_p_p.h index 514cc8a14e2..7ff6279284c 100644 --- a/src/widgets/styles/qmacstyle_mac_p_p.h +++ b/src/widgets/styles/qmacstyle_mac_p_p.h @@ -93,7 +93,9 @@ #include #include #include +#if QT_CONFIG(treeview) #include +#endif #if QT_CONFIG(tableview) #include #endif diff --git a/src/widgets/styles/qpixmapstyle.cpp b/src/widgets/styles/qpixmapstyle.cpp index de99b6ce7be..88482d28c94 100644 --- a/src/widgets/styles/qpixmapstyle.cpp +++ b/src/widgets/styles/qpixmapstyle.cpp @@ -55,7 +55,6 @@ #include #include #include -#include #include #include #include diff --git a/src/widgets/styles/qwindowsvistastyle_p_p.h b/src/widgets/styles/qwindowsvistastyle_p_p.h index 01fe32c1c67..5d772204a71 100644 --- a/src/widgets/styles/qwindowsvistastyle_p_p.h +++ b/src/widgets/styles/qwindowsvistastyle_p_p.h @@ -77,7 +77,9 @@ #include #include #include +#if QT_CONFIG(treeview) #include +#endif #include #include #if QT_CONFIG(dialogbuttonbox) diff --git a/src/widgets/util/qcompleter_p.h b/src/widgets/util/qcompleter_p.h index c35f70b451b..6629c47e069 100644 --- a/src/widgets/util/qcompleter_p.h +++ b/src/widgets/util/qcompleter_p.h @@ -57,7 +57,7 @@ #ifndef QT_NO_COMPLETER -#include "QtWidgets/qtreeview.h" +#include "QtWidgets/qabstractitemview.h" #include "QtCore/qabstractproxymodel.h" #include "qcompleter.h" #include "QtWidgets/qitemdelegate.h" diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index 84d81fa0892..6a8167b5e58 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -56,7 +56,9 @@ #include #include #include +#if QT_CONFIG(treeview) #include +#endif #include #include #include @@ -2602,7 +2604,7 @@ void QComboBox::showPopup() int count = 0; QStack toCheck; toCheck.push(view()->rootIndex()); -#ifndef QT_NO_TREEVIEW +#if QT_CONFIG(treeview) QTreeView *treeView = qobject_cast(view()); if (treeView && treeView->header() && !treeView->header()->isHidden()) listHeight += treeView->header()->height(); @@ -2614,7 +2616,7 @@ void QComboBox::showPopup() if (!idx.isValid()) continue; listHeight += view()->visualRect(idx).height(); -#ifndef QT_NO_TREEVIEW +#if QT_CONFIG(treeview) if (d->model->hasChildren(idx) && treeView && treeView->isExpanded(idx)) toCheck.push(idx); #endif From 184d80f5a0d6764745ab77487620eb41679226f0 Mon Sep 17 00:00:00 2001 From: Kai Uwe Broulik Date: Wed, 21 Jun 2017 10:49:59 +0200 Subject: [PATCH 08/27] QDialogButtonBox: Don't overwrite shortcut with standardButtonShortcut MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit de63bbd2f806b0219a60775017899cedb121581f introduced a new QPlatformTheme::standardButtonShortcut which would then unconditionally overwrite the QPushButton shortcut, even when empty, breaking activating mnemonics potentially included in the button's text. Task-number: QTBUG-61197 Change-Id: I2a5a460a820a5ab4054eb44f349066aaeca1436f Reviewed-by: Marco Martin Reviewed-by: Alexander Volkov Reviewed-by: Tor Arne Vestbø --- src/widgets/widgets/qdialogbuttonbox.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/widgets/widgets/qdialogbuttonbox.cpp b/src/widgets/widgets/qdialogbuttonbox.cpp index a3e55114bb3..90cb17da592 100644 --- a/src/widgets/widgets/qdialogbuttonbox.cpp +++ b/src/widgets/widgets/qdialogbuttonbox.cpp @@ -411,7 +411,9 @@ QPushButton *QDialogButtonBoxPrivate::createButton(QDialogButtonBox::StandardBut else addButton(button, static_cast(role), doLayout); #if QT_CONFIG(shortcut) - button->setShortcut(QGuiApplicationPrivate::platformTheme()->standardButtonShortcut(sbutton)); + const QKeySequence standardShortcut = QGuiApplicationPrivate::platformTheme()->standardButtonShortcut(sbutton); + if (!standardShortcut.isEmpty()) + button->setShortcut(standardShortcut); #endif return button; } From 0b6bf289fdffd731af13ad80f1008001a1423dbd Mon Sep 17 00:00:00 2001 From: Jake Petroules Date: Sat, 15 Jul 2017 03:30:53 -0700 Subject: [PATCH 09/27] Update OS version constants in qsystemdetection.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I8c8fa8861280948bf8488c4465a359858bb625e0 Reviewed-by: Tor Arne Vestbø Reviewed-by: Thiago Macieira --- src/corelib/global/qsystemdetection.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/corelib/global/qsystemdetection.h b/src/corelib/global/qsystemdetection.h index 3133b4a719a..4a2c3f79bba 100644 --- a/src/corelib/global/qsystemdetection.h +++ b/src/corelib/global/qsystemdetection.h @@ -267,6 +267,9 @@ # if !defined(__MAC_10_12) # define __MAC_10_12 101200 # endif +# if !defined(__MAC_10_13) +# define __MAC_10_13 101300 +# endif # if !defined(MAC_OS_X_VERSION_10_7) # define MAC_OS_X_VERSION_10_7 1070 # endif @@ -285,6 +288,9 @@ # if !defined(MAC_OS_X_VERSION_10_12) # define MAC_OS_X_VERSION_10_12 101200 # endif +# if !defined(MAC_OS_X_VERSION_10_13) +# define MAC_OS_X_VERSION_10_13 101300 +# endif # # if !defined(__IPHONE_4_3) # define __IPHONE_4_3 40300 @@ -337,6 +343,18 @@ # if !defined(__IPHONE_10_0) # define __IPHONE_10_0 100000 # endif +# if !defined(__IPHONE_10_1) +# define __IPHONE_10_1 100100 +# endif +# if !defined(__IPHONE_10_2) +# define __IPHONE_10_2 100200 +# endif +# if !defined(__IPHONE_10_3) +# define __IPHONE_10_3 100300 +# endif +# if !defined(__IPHONE_11_0) +# define __IPHONE_11_0 110000 +# endif #endif #ifdef __LSB_VERSION__ From 2d54aac427d588be73a28e52fc59d0e62f975941 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Mon, 10 Jul 2017 15:41:37 +0200 Subject: [PATCH 10/27] Fix warning messages in QWindowsPipeReader/Writer We forgot to update the warnings when removing qt_cancelIo. Also, use %p instead of %x, because HANDLE is void*. This amends commit fade2958. Change-Id: Ia11d7d094aa6beb939e0be4bbe4ab3654eaa1c02 Reviewed-by: Oswald Buddenhagen --- src/corelib/io/qwindowspipereader.cpp | 2 +- src/corelib/io/qwindowspipewriter.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/io/qwindowspipereader.cpp b/src/corelib/io/qwindowspipereader.cpp index 827ed43b633..4065b194468 100644 --- a/src/corelib/io/qwindowspipereader.cpp +++ b/src/corelib/io/qwindowspipereader.cpp @@ -98,7 +98,7 @@ void QWindowsPipeReader::stop() if (!CancelIoEx(handle, &overlapped)) { const DWORD dwError = GetLastError(); if (dwError != ERROR_NOT_FOUND) { - qErrnoWarning(dwError, "QWindowsPipeReader: qt_cancelIo on handle %x failed.", + qErrnoWarning(dwError, "QWindowsPipeReader: CancelIoEx on handle %p failed.", handle); } } diff --git a/src/corelib/io/qwindowspipewriter.cpp b/src/corelib/io/qwindowspipewriter.cpp index 3ab2c70c751..d6ee4741e31 100644 --- a/src/corelib/io/qwindowspipewriter.cpp +++ b/src/corelib/io/qwindowspipewriter.cpp @@ -211,7 +211,7 @@ void QWindowsPipeWriter::stop() if (!CancelIoEx(handle, &overlapped)) { const DWORD dwError = GetLastError(); if (dwError != ERROR_NOT_FOUND) { - qErrnoWarning(dwError, "QWindowsPipeWriter: qt_cancelIo on handle %x failed.", + qErrnoWarning(dwError, "QWindowsPipeWriter: CancelIoEx on handle %p failed.", handle); } } From 8f3f02b910c86b637c2980f9af7713e7516155af Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Wed, 12 Jul 2017 11:20:57 +0200 Subject: [PATCH 11/27] Doc: Add Apple OS deployment targets to the qmake Manual The following variables were not documented: - QMAKE_IOS_DEPLOYMENT_TARGET - QMAKE_TVOS_DEPLOYMENT_TARGET - QMAKE_WATCHOS_DEPLOYMENT_TARGET Change-Id: I5cfb6c0024d92e943aed882fd01bc2a4f2c7c042 Reviewed-by: Jake Petroules --- qmake/doc/src/qmake-manual.qdoc | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/qmake/doc/src/qmake-manual.qdoc b/qmake/doc/src/qmake-manual.qdoc index 0af6f8ca763..4e025b9e7c1 100644 --- a/qmake/doc/src/qmake-manual.qdoc +++ b/qmake/doc/src/qmake-manual.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2017 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. @@ -1809,6 +1809,14 @@ \note Most of the time, the default \c{Info.plist} is good enough. + \section1 QMAKE_IOS_DEPLOYMENT_TARGET + + \note This variable is used on the iOS platform only. + + Specifies the hard minimum version of iOS that the application supports. + + For more information, see \l {Expressing Supported iOS Versions}. + \section1 QMAKE_LFLAGS Specifies a general set of flags that are passed to @@ -2251,6 +2259,22 @@ This is only utilized if the \l{VERSION} or \l{RC_ICONS} variable is set and the \l{RC_FILE} and \l{RES_FILE} variables are not set. + \section1 QMAKE_TVOS_DEPLOYMENT_TARGET + + \note This variable is used on the tvOS platform only. + + Specifies the hard minimum version of tvOS that the application supports. + + For more information, see \l {Expressing Supported iOS Versions}. + + \section1 QMAKE_WATCHOS_DEPLOYMENT_TARGET + + \note This variable is used on the watchOS platform only. + + Specifies the hard minimum version of watchOS that the application supports. + + For more information, see \l {Expressing Supported iOS Versions}. + \section1 QT Specifies the \l{All Modules}{Qt modules} that are used by your project. For From 768922def5ad2c814bb69a7794e271f1dcb8fc98 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Wed, 12 Jul 2017 11:39:38 +0200 Subject: [PATCH 12/27] Doc: Update docs for QMAKE_MACOSX_DEPLOYMENT_TARGET in qmake Manual The old docs contained obsolete information. Also, the new docs match the new docs for the other Apple OS deployment targets. Change-Id: Id773fa2086f291d8a2552fe1b339ec1e13c19d74 Reviewed-by: Jake Petroules --- qmake/doc/src/qmake-manual.qdoc | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/qmake/doc/src/qmake-manual.qdoc b/qmake/doc/src/qmake-manual.qdoc index 4e025b9e7c1..216cc30af1c 100644 --- a/qmake/doc/src/qmake-manual.qdoc +++ b/qmake/doc/src/qmake-manual.qdoc @@ -2109,12 +2109,11 @@ \section1 QMAKE_MACOSX_DEPLOYMENT_TARGET - This variable only takes effect when building on \macos. On that - platform, the variable will be forwarded to the MACOSX_DEPLOYMENT_TARGET - environment variable, which is interpreted by the compiler or linker. - For more information, see the - \l{Qt for macOS - Deployment#macOS Version Dependencies}{Deploying - an Application on \macos} document. + \note This variable is used on the \macos platform only. + + Specifies the hard minimum version of \macos that the application supports. + + For more information, see \l{macOS Version Dependencies}. \section1 QMAKE_MAKEFILE From 0345608d169d7c59768e461a9ec61bb7563cbaa6 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 13 Jun 2017 15:17:26 +0200 Subject: [PATCH 13/27] Allow fusion style to follow platform theme on button icons Do not try to set the default value of dialog buttons in fusion, but let the common style handle it that asks the platform theme. This adds icons to dialog buttons on platforms that usually has that (such as KDE). Change-Id: I29cfa49cfd993224220bc992c523f5b2df20870d Reviewed-by: Friedemann Kleint Reviewed-by: David Faure --- src/widgets/styles/qfusionstyle.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/widgets/styles/qfusionstyle.cpp b/src/widgets/styles/qfusionstyle.cpp index dd8b1b1d69a..b6e61e7cc9f 100644 --- a/src/widgets/styles/qfusionstyle.cpp +++ b/src/widgets/styles/qfusionstyle.cpp @@ -3712,7 +3712,6 @@ int QFusionStyle::styleHint(StyleHint hint, const QStyleOption *option, const QW case SH_ScrollView_FrameOnlyAroundContents: case SH_Menu_AllowActiveAndDisabled: case SH_MainWindow_SpaceBelowMenuBar: - case SH_DialogButtonBox_ButtonsHaveIcons: case SH_MessageBox_CenterButtons: case SH_RubberBand_Mask: return 0; From c7ec07d40115bef849574c81d619b629af9434a9 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 12 Jul 2017 14:20:54 +0200 Subject: [PATCH 14/27] Do not wait in QWindowsPipe{Reader|Writer}::stop() A deadlock can occur if the user does QLocalSocket *ls = new QLocalSocket; ls->moveToThread(t); ... delete ls; Then QLocalSocket calls QWindowsPipeReader::stop() in a different thread than the I/O operation is running in. The waitForNotified(-1) call would then wait indefinitely until the I/O thread is in alertable wait state again. Especially on application shut down this might never be the case, and the application would deadlock. Solve this by detaching the Overlapped object from the QWindowsPipe{Reader|Writer} in stop() and delete it in the callback. Task-number: QTBUG-61643 Change-Id: Ie262d75c5fd92ac7cf7dfcdbf1519050be9fd3c4 Reviewed-by: Oswald Buddenhagen --- src/corelib/io/qwindowspipereader.cpp | 20 ++++++++++++++------ src/corelib/io/qwindowspipereader_p.h | 2 +- src/corelib/io/qwindowspipewriter.cpp | 20 ++++++++++++++------ src/corelib/io/qwindowspipewriter_p.h | 2 +- 4 files changed, 30 insertions(+), 14 deletions(-) diff --git a/src/corelib/io/qwindowspipereader.cpp b/src/corelib/io/qwindowspipereader.cpp index 4065b194468..b93fed5ba8e 100644 --- a/src/corelib/io/qwindowspipereader.cpp +++ b/src/corelib/io/qwindowspipereader.cpp @@ -57,7 +57,7 @@ void QWindowsPipeReader::Overlapped::clear() QWindowsPipeReader::QWindowsPipeReader(QObject *parent) : QObject(parent), handle(INVALID_HANDLE_VALUE), - overlapped(this), + overlapped(nullptr), readBufferMaxSize(0), actualReadBufferSize(0), stopped(true), @@ -74,6 +74,7 @@ QWindowsPipeReader::QWindowsPipeReader(QObject *parent) QWindowsPipeReader::~QWindowsPipeReader() { stop(); + delete overlapped; } /*! @@ -95,14 +96,16 @@ void QWindowsPipeReader::stop() { stopped = true; if (readSequenceStarted) { - if (!CancelIoEx(handle, &overlapped)) { + overlapped->pipeReader = nullptr; + if (!CancelIoEx(handle, overlapped)) { const DWORD dwError = GetLastError(); if (dwError != ERROR_NOT_FOUND) { qErrnoWarning(dwError, "QWindowsPipeReader: CancelIoEx on handle %p failed.", handle); } } - waitForNotification(-1); + overlapped = nullptr; // The object will be deleted in the I/O callback. + readSequenceStarted = false; } } @@ -232,8 +235,10 @@ void QWindowsPipeReader::startAsyncRead() stopped = false; readSequenceStarted = true; - overlapped.clear(); - if (!ReadFileEx(handle, ptr, bytesToRead, &overlapped, &readFileCompleted)) { + if (!overlapped) + overlapped = new Overlapped(this); + overlapped->clear(); + if (!ReadFileEx(handle, ptr, bytesToRead, overlapped, &readFileCompleted)) { readSequenceStarted = false; const DWORD dwError = GetLastError(); @@ -260,7 +265,10 @@ void QWindowsPipeReader::readFileCompleted(DWORD errorCode, DWORD numberOfBytesT OVERLAPPED *overlappedBase) { Overlapped *overlapped = static_cast(overlappedBase); - overlapped->pipeReader->notified(errorCode, numberOfBytesTransfered); + if (overlapped->pipeReader) + overlapped->pipeReader->notified(errorCode, numberOfBytesTransfered); + else + delete overlapped; } /*! diff --git a/src/corelib/io/qwindowspipereader_p.h b/src/corelib/io/qwindowspipereader_p.h index 74ff5250acf..e52aa4c33d2 100644 --- a/src/corelib/io/qwindowspipereader_p.h +++ b/src/corelib/io/qwindowspipereader_p.h @@ -105,7 +105,7 @@ private: }; HANDLE handle; - Overlapped overlapped; + Overlapped *overlapped; qint64 readBufferMaxSize; QRingBuffer readBuffer; qint64 actualReadBufferSize; diff --git a/src/corelib/io/qwindowspipewriter.cpp b/src/corelib/io/qwindowspipewriter.cpp index d6ee4741e31..7eb6dd03898 100644 --- a/src/corelib/io/qwindowspipewriter.cpp +++ b/src/corelib/io/qwindowspipewriter.cpp @@ -56,7 +56,7 @@ void QWindowsPipeWriter::Overlapped::clear() QWindowsPipeWriter::QWindowsPipeWriter(HANDLE pipeWriteEnd, QObject *parent) : QObject(parent), handle(pipeWriteEnd), - overlapped(this), + overlapped(nullptr), numberOfBytesToWrite(0), pendingBytesWrittenValue(0), stopped(true), @@ -72,6 +72,7 @@ QWindowsPipeWriter::QWindowsPipeWriter(HANDLE pipeWriteEnd, QObject *parent) QWindowsPipeWriter::~QWindowsPipeWriter() { stop(); + delete overlapped; } bool QWindowsPipeWriter::waitForWrite(int msecs) @@ -122,7 +123,10 @@ void QWindowsPipeWriter::writeFileCompleted(DWORD errorCode, DWORD numberOfBytes OVERLAPPED *overlappedBase) { Overlapped *overlapped = static_cast(overlappedBase); - overlapped->pipeWriter->notified(errorCode, numberOfBytesTransfered); + if (overlapped->pipeWriter) + overlapped->pipeWriter->notified(errorCode, numberOfBytesTransfered); + else + delete overlapped; } /*! @@ -185,13 +189,15 @@ bool QWindowsPipeWriter::write(const QByteArray &ba) if (writeSequenceStarted) return false; - overlapped.clear(); + if (!overlapped) + overlapped = new Overlapped(this); + overlapped->clear(); buffer = ba; numberOfBytesToWrite = buffer.size(); stopped = false; writeSequenceStarted = true; if (!WriteFileEx(handle, buffer.constData(), numberOfBytesToWrite, - &overlapped, &writeFileCompleted)) { + overlapped, &writeFileCompleted)) { writeSequenceStarted = false; numberOfBytesToWrite = 0; buffer.clear(); @@ -208,14 +214,16 @@ void QWindowsPipeWriter::stop() bytesWrittenPending = false; pendingBytesWrittenValue = 0; if (writeSequenceStarted) { - if (!CancelIoEx(handle, &overlapped)) { + overlapped->pipeWriter = nullptr; + if (!CancelIoEx(handle, overlapped)) { const DWORD dwError = GetLastError(); if (dwError != ERROR_NOT_FOUND) { qErrnoWarning(dwError, "QWindowsPipeWriter: CancelIoEx on handle %p failed.", handle); } } - waitForNotification(-1); + overlapped = nullptr; // The object will be deleted in the I/O callback. + writeSequenceStarted = false; } } diff --git a/src/corelib/io/qwindowspipewriter_p.h b/src/corelib/io/qwindowspipewriter_p.h index c43e986f344..c8252e2a4b5 100644 --- a/src/corelib/io/qwindowspipewriter_p.h +++ b/src/corelib/io/qwindowspipewriter_p.h @@ -143,7 +143,7 @@ private: }; HANDLE handle; - Overlapped overlapped; + Overlapped *overlapped; QByteArray buffer; qint64 numberOfBytesToWrite; qint64 pendingBytesWrittenValue; From f3c39a69bc5fd9188f030777a8a9ed350e7067fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 14 Jul 2017 16:48:27 +0200 Subject: [PATCH 15/27] macOS: Don't assume the proposed fullscreen size matches the screen size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sometimes AppKit will pass in a proposed size that's smaller than the geometry of the screen. We don't know why, but shouldn't assert. Change-Id: I9970c5f587e1e0fb3f2fa932de5a32ac4e1eb76d Reviewed-by: Morten Johan Sørvig Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/cocoa/qnswindowdelegate.mm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/cocoa/qnswindowdelegate.mm b/src/plugins/platforms/cocoa/qnswindowdelegate.mm index e5041fb8634..8295d4a36c3 100644 --- a/src/plugins/platforms/cocoa/qnswindowdelegate.mm +++ b/src/plugins/platforms/cocoa/qnswindowdelegate.mm @@ -88,9 +88,9 @@ */ - (NSSize)window:(NSWindow *)window willUseFullScreenContentSize:(NSSize)proposedSize { - Q_UNUSED(window); - Q_ASSERT(NSEqualSizes(m_cocoaWindow->screen()->geometry().size().toCGSize(), proposedSize)); - return proposedSize; + Q_UNUSED(proposedSize); + Q_ASSERT(window == m_cocoaWindow->nativeWindow()); + return m_cocoaWindow->screen()->geometry().size().toCGSize(); } #endif From 61f020662090258bb5931cc10822848bbc96aaab Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Fri, 14 Jul 2017 08:09:19 +0200 Subject: [PATCH 16/27] Revert "Windows: Fallback to d3d9 when in a VM on VMWare Workstation 12" Revert SHA1 - b1708efeeb31242a4a0d932f42caf3808b00bc28 as it causes a problem with QtMultimedia. Change-Id: I0ba366fa6ddccff3715917f5f455b20c73c2e49e Reviewed-by: Simon Hausmann --- .../platforms/windows/openglblacklists/default.json | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/plugins/platforms/windows/openglblacklists/default.json b/src/plugins/platforms/windows/openglblacklists/default.json index 6515f028306..69f4a54d056 100644 --- a/src/plugins/platforms/windows/openglblacklists/default.json +++ b/src/plugins/platforms/windows/openglblacklists/default.json @@ -126,18 +126,6 @@ "features": [ "disable_desktopgl" ] - }, - { - "id": 11, - "description": "VMWare Workstation Player 12 has insufficient support for OpenGL", - "vendor_id": "0x15AD", - "device_id": [ "0x0405" ], - "os": { - "type": "win" - }, - "features": [ - "disable_desktopgl", "disable_d3d11" - ] } ] } From c08dc1e04f4e9301621223d64b5b34ee9bbad84a Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 13 Jun 2017 15:21:24 +0200 Subject: [PATCH 17/27] Read more KDE configuration in the KDE platform theme Adds the hints that are read and used by the plasma-integration platform theme, so naked Qt applications can integrate just as well on this front. Change-Id: I45a113e0081ea96c8cf543c22b28b69280ae7619 Reviewed-by: Friedemann Kleint Reviewed-by: David Faure --- .../themes/genericunix/qgenericunixthemes.cpp | 49 +++++++++++++++---- 1 file changed, 40 insertions(+), 9 deletions(-) diff --git a/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp b/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp index 2b4c6a000fe..323e8fd13bf 100644 --- a/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp +++ b/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp @@ -264,10 +264,6 @@ public: QKdeThemePrivate(const QStringList &kdeDirs, int kdeVersion) : kdeDirs(kdeDirs) , kdeVersion(kdeVersion) - , toolButtonStyle(Qt::ToolButtonTextBesideIcon) - , toolBarIconSize(0) - , singleClick(true) - , wheelScrollLines(3) { } static QString kdeGlobals(const QString &kdeDir, int kdeVersion) @@ -290,10 +286,15 @@ public: QString iconThemeName; QString iconFallbackThemeName; QStringList styleNames; - int toolButtonStyle; - int toolBarIconSize; - bool singleClick; - int wheelScrollLines; + int toolButtonStyle = Qt::ToolButtonTextBesideIcon; + int toolBarIconSize = 0; + bool singleClick = true; + bool showIconsOnPushButtons = true; + int wheelScrollLines = 3; + int doubleClickInterval = 400; + int startDragDist = 10; + int startDragTime = 500; + int cursorBlinkRate = 1000; }; void QKdeThemePrivate::refresh() @@ -329,6 +330,10 @@ void QKdeThemePrivate::refresh() if (singleClickValue.isValid()) singleClick = singleClickValue.toBool(); + const QVariant showIconsOnPushButtonsValue = readKdeSetting(QStringLiteral("KDE/ShowIconsOnPushButtons"), kdeDirs, kdeVersion, kdeSettings); + if (showIconsOnPushButtonsValue.isValid()) + showIconsOnPushButtons = showIconsOnPushButtonsValue.toBool(); + const QVariant themeValue = readKdeSetting(QStringLiteral("Icons/Theme"), kdeDirs, kdeVersion, kdeSettings); if (themeValue.isValid()) iconThemeName = themeValue.toString(); @@ -352,6 +357,24 @@ void QKdeThemePrivate::refresh() if (wheelScrollLinesValue.isValid()) wheelScrollLines = wheelScrollLinesValue.toInt(); + const QVariant doubleClickIntervalValue = readKdeSetting(QStringLiteral("KDE/DoubleClickInterval"), kdeDirs, kdeVersion, kdeSettings); + if (doubleClickIntervalValue.isValid()) + doubleClickInterval = doubleClickIntervalValue.toInt(); + + const QVariant startDragDistValue = readKdeSetting(QStringLiteral("KDE/StartDragDist"), kdeDirs, kdeVersion, kdeSettings); + if (startDragDistValue.isValid()) + startDragDist = startDragDistValue.toInt(); + + const QVariant startDragTimeValue = readKdeSetting(QStringLiteral("KDE/StartDragTime"), kdeDirs, kdeVersion, kdeSettings); + if (startDragTimeValue.isValid()) + startDragTime = startDragTimeValue.toInt(); + + const QVariant cursorBlinkRateValue = readKdeSetting(QStringLiteral("KDE/CursorBlinkRate"), kdeDirs, kdeVersion, kdeSettings); + if (cursorBlinkRateValue.isValid()) { + cursorBlinkRate = cursorBlinkRateValue.toInt(); + cursorBlinkRate = cursorBlinkRate > 0 ? qBound(200, cursorBlinkRate, 2000) : 0; + } + // Read system font, ignore 'smallestReadableFont' if (QFont *systemFont = kdeFont(readKdeSetting(QStringLiteral("font"), kdeDirs, kdeVersion, kdeSettings))) resources.fonts[QPlatformTheme::SystemFont] = systemFont; @@ -527,7 +550,7 @@ QVariant QKdeTheme::themeHint(QPlatformTheme::ThemeHint hint) const case QPlatformTheme::UseFullScreenForPopupMenu: return QVariant(true); case QPlatformTheme::DialogButtonBoxButtonsHaveIcons: - return QVariant(true); + return QVariant(d->showIconsOnPushButtons); case QPlatformTheme::DialogButtonBoxLayout: return QVariant(QPlatformDialogHelper::KdeLayout); case QPlatformTheme::ToolButtonStyle: @@ -550,6 +573,14 @@ QVariant QKdeTheme::themeHint(QPlatformTheme::ThemeHint hint) const return QVariant(d->singleClick); case QPlatformTheme::WheelScrollLines: return QVariant(d->wheelScrollLines); + case QPlatformTheme::MouseDoubleClickInterval: + return QVariant(d->doubleClickInterval); + case QPlatformTheme::StartDragTime: + return QVariant(d->startDragTime); + case QPlatformTheme::StartDragDistance: + return QVariant(d->startDragDist); + case QPlatformTheme::CursorFlashTime: + return QVariant(d->cursorBlinkRate); case QPlatformTheme::UiEffects: return QVariant(int(HoverEffect)); default: From 4a7ec2d9b0c353d40ab9702e8d7b7fdab52dfd0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 18 Jul 2017 14:58:31 +0200 Subject: [PATCH 18/27] testlib: Allow tailing comments in blacklist files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-61987 Change-Id: I27219a6d06d7a81514e3f7b2ad5469676f724e04 Reviewed-by: Simon Hausmann Reviewed-by: Tor Arne Vestbø --- src/testlib/qtestblacklist.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/testlib/qtestblacklist.cpp b/src/testlib/qtestblacklist.cpp index 75186d93aed..57661bb389e 100644 --- a/src/testlib/qtestblacklist.cpp +++ b/src/testlib/qtestblacklist.cpp @@ -54,7 +54,7 @@ QT_BEGIN_NAMESPACE /* The BLACKLIST file format is a grouped listing of keywords. - Blank lines and lines starting with # are simply ignored. An initial #-line + Blank lines and everything after # is simply ignored. An initial #-line referring to this documentation is kind to readers. Comments can also be used to indicate the reasons for ignoring particular cases. @@ -247,8 +247,12 @@ void parseBlackList() QByteArray function; while (!ignored.atEnd()) { - QByteArray line = ignored.readLine().simplified(); - if (line.isEmpty() || line.startsWith('#')) + QByteArray line = ignored.readLine(); + const int commentPosition = line.indexOf('#'); + if (commentPosition >= 0) + line.truncate(commentPosition); + line = line.simplified(); + if (line.isEmpty()) continue; if (line.startsWith('[')) { function = line.mid(1, line.length() - 2); From 07c0e0fdcf6ccea2a60b2acc7059f56a834ad040 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Fri, 14 Jul 2017 10:40:49 +0200 Subject: [PATCH 19/27] QAsn1Element - fix toDateTime function ASN UTCTime uses two characters to encode a year (YY). When converting it into QDate, it's quite naive to just add 2000. According to RFC 2459, these YY represent dates in the range [1950, 2049]. This patch also introduces a helper function doing the checked conversion from a string to int (to be reused in the following-up patches). Task-number: QTBUG-61934 Change-Id: I3f6f471d24e8357b83b2f5973023b2b842751389 Reviewed-by: Edward Welbourne Reviewed-by: Timur Pocheptsov --- src/network/ssl/qasn1element.cpp | 34 +++++++++++++++++-- .../ssl/qasn1element/tst_qasn1element.cpp | 27 +++++++++++++++ 2 files changed, 58 insertions(+), 3 deletions(-) diff --git a/src/network/ssl/qasn1element.cpp b/src/network/ssl/qasn1element.cpp index dc59c41d590..6558643386d 100644 --- a/src/network/ssl/qasn1element.cpp +++ b/src/network/ssl/qasn1element.cpp @@ -45,6 +45,8 @@ #include #include +#include + QT_BEGIN_NAMESPACE typedef QMap OidNameMap; @@ -82,6 +84,27 @@ static OidNameMap createOidMap() } Q_GLOBAL_STATIC_WITH_ARGS(OidNameMap, oidNameMap, (createOidMap())) +static bool stringToNonNegativeInt(const QByteArray &asnString, int *val) +{ + // Helper function for toDateTime(), which handles chunking of the original + // string into smaller sub-components, so we expect the whole 'asnString' to + // be a valid non-negative number. + Q_ASSERT(val); + + // We want the C locale, as used by QByteArray; however, no leading sign is + // allowed (which QByteArray would accept), so we have to check the data: + const std::locale localeC; + for (char v : asnString) { + if (!std::isdigit(v, localeC)) + return false; + } + + bool ok = false; + *val = asnString.toInt(&ok); + Q_ASSERT(ok && *val >= 0); + return true; +} + QAsn1Element::QAsn1Element(quint8 type, const QByteArray &value) : mType(type) , mValue(value) @@ -231,15 +254,19 @@ bool QAsn1Element::toBool(bool *ok) const QDateTime QAsn1Element::toDateTime() const { if (mValue.endsWith('Z')) { - if (mType == UtcTimeType && mValue.size() == 13) - return QDateTime(QDate(2000 + mValue.mid(0, 2).toInt(), + if (mType == UtcTimeType && mValue.size() == 13) { + int year = 0; + if (!stringToNonNegativeInt(mValue.mid(0, 2), &year)) + return QDateTime(); + // RFC 2459: YY represents a year in the range [1950, 2049] + return QDateTime(QDate(year < 50 ? 2000 + year : 1900 + year, mValue.mid(2, 2).toInt(), mValue.mid(4, 2).toInt()), QTime(mValue.mid(6, 2).toInt(), mValue.mid(8, 2).toInt(), mValue.mid(10, 2).toInt()), Qt::UTC); - else if (mType == GeneralizedTimeType && mValue.size() == 15) + } else if (mType == GeneralizedTimeType && mValue.size() == 15) { return QDateTime(QDate(mValue.mid(0, 4).toInt(), mValue.mid(4, 2).toInt(), mValue.mid(6, 2).toInt()), @@ -247,6 +274,7 @@ QDateTime QAsn1Element::toDateTime() const mValue.mid(10, 2).toInt(), mValue.mid(12, 2).toInt()), Qt::UTC); + } } return QDateTime(); } diff --git a/tests/auto/network/ssl/qasn1element/tst_qasn1element.cpp b/tests/auto/network/ssl/qasn1element/tst_qasn1element.cpp index 401ed855870..0928ecc5a1e 100644 --- a/tests/auto/network/ssl/qasn1element/tst_qasn1element.cpp +++ b/tests/auto/network/ssl/qasn1element/tst_qasn1element.cpp @@ -134,6 +134,33 @@ void tst_QAsn1Element::dateTime_data() QTest::newRow("UTCTime - no trailing Z") << QByteArray::fromHex("170d30373034313730373430323659") << QDateTime(); + QTest::newRow("UTCTime - year 1950") + << QByteArray::fromHex("170d3530313232343035353530305a") + << QDateTime(QDate(1950, 12, 24), QTime(5, 55), Qt::UTC); + QTest::newRow("UTCTime - year 1999") + << QByteArray::fromHex("170d3939313232343035353530305a") + << QDateTime(QDate(1999, 12, 24), QTime(5, 55), Qt::UTC); + QTest::newRow("UTCTime - year 2000") + << QByteArray::fromHex("170d3030313232343035353530305a") + << QDateTime(QDate(2000, 12, 24), QTime(5, 55), Qt::UTC); + QTest::newRow("UTCTime - year 2049") + << QByteArray::fromHex("170d3439313232343035353530305a") + << QDateTime(QDate(2049, 12, 24), QTime(5, 55), Qt::UTC); + QTest::newRow("UTCTime - invalid year ('-9')") + << QByteArray::fromHex("170d2d39313232343035353530305a") + << QDateTime(); + QTest::newRow("UTCTime - invalid year ('*9')") + << QByteArray::fromHex("170d2a39313232343035353530305a") + << QDateTime(); + QTest::newRow("UTCTime - invalid year ('5*')") + << QByteArray::fromHex("170d352a313232343035353530305a") + << QDateTime(); + QTest::newRow("UTCTime - invalid year ('AB')") + << QByteArray::fromHex("170d4142313232343035353530305a") + << QDateTime(); + QTest::newRow("UTCTime - invalid year ('+1')") + << QByteArray::fromHex("170d2b31313232343035353530305a") + << QDateTime(); QTest::newRow("GeneralizedTime - 20510829095341Z") << QByteArray::fromHex("180f32303531303832393039353334315a") << QDateTime(QDate(2051, 8, 29), QTime(9, 53, 41), Qt::UTC); From 9a69a1b969c114f7b4a21a5607b2ec70991dc7c7 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Thu, 22 Jun 2017 12:26:54 +0200 Subject: [PATCH 20/27] Doc: Fix snippet for QUrl::isValid() documentation qDebug(...) expects a const char *, not a QString. Change-Id: Ie4489c29440e328a732ed026eae3859eb8855ea5 Reviewed-by: Thiago Macieira Reviewed-by: Friedemann Kleint --- src/corelib/doc/snippets/code/src_corelib_io_qurl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/doc/snippets/code/src_corelib_io_qurl.cpp b/src/corelib/doc/snippets/code/src_corelib_io_qurl.cpp index 805646c7d99..b2a22820850 100644 --- a/src/corelib/doc/snippets/code/src_corelib_io_qurl.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_io_qurl.cpp @@ -62,7 +62,7 @@ QUrl url = QUrl::fromEncoded("http://qt-project.org/List%20of%20holidays.xml"); //! [2] bool checkUrl(const QUrl &url) { if (!url.isValid()) { - qDebug(QString("Invalid URL: %1").arg(url.toString())); + qDebug("Invalid URL: %s", qUtf8Printable(url.toString())); return false; } From 54c2bfc9dbc445be94ba5031d96f93f497246744 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Thu, 20 Apr 2017 11:48:38 +0200 Subject: [PATCH 21/27] Doc: Clarify limitations of category filter As suggested by ogoffart. Change-Id: I15747869147819799b14dfe0670ff2225f76fc03 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/io/qloggingcategory.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/io/qloggingcategory.cpp b/src/corelib/io/qloggingcategory.cpp index 69af936bca0..3eaf10c53ed 100644 --- a/src/corelib/io/qloggingcategory.cpp +++ b/src/corelib/io/qloggingcategory.cpp @@ -411,8 +411,8 @@ QLoggingCategory *QLoggingCategory::defaultCategory() filter is free to change the respective category configuration with \l setEnabled(). - The filter might be called concurrently from different threads, and - therefore has to be reentrant. + The filter might be called from different threads, but never concurrently. + The filter shall not call any static functions of QLoggingCategory. Example: \snippet qloggingcategory/main.cpp 21 From 3f18dadeeb36e8add4f82f6e6b63373e1bac5e27 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Thu, 20 Apr 2017 11:00:46 +0200 Subject: [PATCH 22/27] Doc: QLoggingCategory::setEnabled() should only be called in filter Change-Id: Ib159c45ca259af125e48e3dfe59d64abc5f81f81 Reviewed-by: Thiago Macieira --- src/corelib/io/qloggingcategory.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/corelib/io/qloggingcategory.cpp b/src/corelib/io/qloggingcategory.cpp index 3eaf10c53ed..4256d4b6e15 100644 --- a/src/corelib/io/qloggingcategory.cpp +++ b/src/corelib/io/qloggingcategory.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2017 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -334,12 +334,11 @@ bool QLoggingCategory::isEnabled(QtMsgType msgtype) const /*! Changes the message type \a type for the category to \a enable. - \note Changes only affect the current QLoggingCategory object, and won't - change the settings of other objects for the same category name. - Use either \l setFilterRules() or \l installFilter() to change the - configuration globally. + This method is meant to be used only from inside a filter + installed by \l installFilter(). See \l {Configuring Categories} for + an overview on how to configure categories globally. - \note \c QtFatalMsg cannot be changed. It will always return \c true. + \note \c QtFatalMsg cannot be changed. It will always remain \c true. */ void QLoggingCategory::setEnabled(QtMsgType type, bool enable) { From c0bd7ade1aa49ed6877e5f13a74bcb72ff662062 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 9 Jul 2017 12:29:26 -0700 Subject: [PATCH 23/27] QFileSystemEngine::id/Windows: Use the volume ID too The MS documentation says that the high/low parts uniquely identify a file within a system, but they actually mean the filesystem. The details on how it's allocated make that clear. So we need the volume identifier. Change-Id: I658f552684924f8aa2cafffd14cfc03c5a09c0e9 Reviewed-by: Friedemann Kleint Reviewed-by: Kai Koehne Reviewed-by: Maurice Kalinowski --- src/corelib/io/qfilesystemengine_win.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index e4a7ea48918..5ed2671ab4e 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -571,19 +571,21 @@ typedef struct _FILE_ID_INFO { // File ID for Windows up to version 7. static inline QByteArray fileId(HANDLE handle) { - QByteArray result; #ifndef Q_OS_WINRT BY_HANDLE_FILE_INFORMATION info; if (GetFileInformationByHandle(handle, &info)) { - result = QByteArray::number(uint(info.nFileIndexLow), 16); - result += ':'; - result += QByteArray::number(uint(info.nFileIndexHigh), 16); + char buffer[sizeof "01234567:0123456701234567"]; + qsnprintf(buffer, sizeof(buffer), "%lx:%08lx%08lx", + info.dwVolumeSerialNumber, + info.nFileIndexHigh, + info.nFileIndexLow); + return buffer; } #else // !Q_OS_WINRT Q_UNUSED(handle); Q_UNIMPLEMENTED(); #endif // Q_OS_WINRT - return result; + return QByteArray(); } // File ID for Windows starting from version 8. From f3205a49498d3084f46bc2c2abcd085c8436553b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 29 Jun 2017 21:18:04 -0700 Subject: [PATCH 24/27] Merge qt_error_string and QSystemError This removes a lot of duplicated code that existed in both qglobal.cpp and qsystemerror.cpp, including the hack to get the correct strerror_r signature. This removes the incorrect use of EACCES, EMFILE, ENOENT, and ENOSPC from qt_error_string on Windows. qt_error_string is supposed to be used only with Win32 error codes from GetLastError(), despite there being a lot of uses in cross-platform and even Windows-specific code that pass errno constants. It may or may not work: that depends on whether the constants happen to match. ENOENT matches ERROR_FILE_NOT_FOUND and one could argue that ENOSPC matching ERROR_OUT_OF_PAPER is acceptable, but EMFILE isn't the same as ERROR_BAD_LENGTH nor is EACCES, ERROR_INVALID_DATA. Change-Id: I1eba2b016de74620bfc8fffd14cccb7f77f4b510 Reviewed-by: Friedemann Kleint Reviewed-by: Kai Koehne Reviewed-by: Thiago Macieira --- src/corelib/global/qglobal.cpp | 92 -------------------------- src/corelib/kernel/qsystemerror.cpp | 29 +++++++- src/corelib/kernel/qsystemerror_p.h | 14 +++- tests/auto/tools/qmakelib/evaltest.cpp | 4 ++ 4 files changed, 42 insertions(+), 97 deletions(-) diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 9b76c72c0dc..4223d2a3e13 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -3102,98 +3102,6 @@ Q_CORE_EXPORT unsigned int qt_int_sqrt(unsigned int n) void *qMemCopy(void *dest, const void *src, size_t n) { return memcpy(dest, src, n); } void *qMemSet(void *dest, int c, size_t n) { return memset(dest, c, n); } -#if !defined(Q_OS_WIN) && !defined(QT_NO_THREAD) && !defined(Q_OS_INTEGRITY) && !defined(Q_OS_QNX) && \ - defined(_POSIX_THREAD_SAFE_FUNCTIONS) && _POSIX_VERSION >= 200112L -namespace { - // There are two incompatible versions of strerror_r: - // a) the XSI/POSIX.1 version, which returns an int, - // indicating success or not - // b) the GNU version, which returns a char*, which may or may not - // be the beginning of the buffer we used - // The GNU libc manpage for strerror_r says you should use the XSI - // version in portable code. However, it's impossible to do that if - // _GNU_SOURCE is defined so we use C++ overloading to decide what to do - // depending on the return type - static inline Q_DECL_UNUSED QString fromstrerror_helper(int, const QByteArray &buf) - { - return QString::fromLocal8Bit(buf.constData()); - } - static inline Q_DECL_UNUSED QString fromstrerror_helper(const char *str, const QByteArray &) - { - return QString::fromLocal8Bit(str); - } -} -#endif - -QString qt_error_string(int errorCode) -{ - const char *s = 0; - QString ret; - if (errorCode == -1) { -#if defined(Q_OS_WIN) - errorCode = GetLastError(); -#else - errorCode = errno; -#endif - } - switch (errorCode) { - case 0: - break; - case EACCES: - s = QT_TRANSLATE_NOOP("QIODevice", "Permission denied"); - break; - case EMFILE: - s = QT_TRANSLATE_NOOP("QIODevice", "Too many open files"); - break; - case ENOENT: - s = QT_TRANSLATE_NOOP("QIODevice", "No such file or directory"); - break; - case ENOSPC: - s = QT_TRANSLATE_NOOP("QIODevice", "No space left on device"); - break; - default: { -#if defined(Q_OS_WIN) - // Retrieve the system error message for the last-error code. -# ifndef Q_OS_WINRT - wchar_t *string = 0; - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_ALLOCATE_BUFFER, - NULL, - errorCode, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPWSTR)&string, - 0, - NULL); - ret = QString::fromWCharArray(string); - LocalFree((HLOCAL)string); -# else // !Q_OS_WINRT - __declspec(thread) static wchar_t errorString[4096]; - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - errorCode, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - errorString, - ARRAYSIZE(errorString), - NULL); - ret = QString::fromWCharArray(errorString); -# endif // Q_OS_WINRT - - if (ret.isEmpty() && errorCode == ERROR_MOD_NOT_FOUND) - ret = QString::fromLatin1("The specified module could not be found."); -#elif !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && _POSIX_VERSION >= 200112L && !defined(Q_OS_INTEGRITY) && !defined(Q_OS_QNX) - QByteArray buf(1024, '\0'); - ret = fromstrerror_helper(strerror_r(errorCode, buf.data(), buf.size()), buf); -#else - ret = QString::fromLocal8Bit(strerror(errorCode)); -#endif - break; } - } - if (s) - // ######## this breaks moc build currently -// ret = QCoreApplication::translate("QIODevice", s); - ret = QString::fromLatin1(s); - return ret.trimmed(); -} - // In the C runtime on all platforms access to the environment is not thread-safe. We // add thread-safety for the Qt wrappers. static QBasicMutex environmentMutex; diff --git a/src/corelib/kernel/qsystemerror.cpp b/src/corelib/kernel/qsystemerror.cpp index 3899f24d3b1..6583838a9f7 100644 --- a/src/corelib/kernel/qsystemerror.cpp +++ b/src/corelib/kernel/qsystemerror.cpp @@ -101,6 +101,8 @@ static QString windowsErrorString(int errorCode) if (ret.isEmpty() && errorCode == ERROR_MOD_NOT_FOUND) ret = QString::fromLatin1("The specified module could not be found."); + if (ret.endsWith(QLatin1String("\r\n"))) + ret.chop(2); return ret; } #endif @@ -126,7 +128,7 @@ static QString standardLibraryErrorString(int errorCode) break; default: { #if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && _POSIX_VERSION >= 200112L && !defined(Q_OS_INTEGRITY) && !defined(Q_OS_QNX) - QByteArray buf(1024, '\0'); + QByteArray buf(1024, Qt::Uninitialized); ret = fromstrerror_helper(strerror_r(errorCode, buf.data(), buf.size()), buf); #else ret = QString::fromLocal8Bit(strerror(errorCode)); @@ -141,7 +143,7 @@ static QString standardLibraryErrorString(int errorCode) return ret.trimmed(); } -QString QSystemError::toString() const +QString QSystemError::string(ErrorScope errorScope, int errorCode) { switch(errorScope) { case NativeError: @@ -161,5 +163,26 @@ QString QSystemError::toString() const } } -QT_END_NAMESPACE +QString QSystemError::stdString(int errorCode) +{ + return standardLibraryErrorString(errorCode == -1 ? errno : errorCode); +} +#ifdef Q_OS_WIN +QString QSystemError::windowsString(int errorCode) +{ + return windowsErrorString(errorCode == -1 ? GetLastError() : errorCode); +} + +QString qt_error_string(int code) +{ + return windowsErrorString(code == -1 ? GetLastError() : code); +} +#else +QString qt_error_string(int code) +{ + return standardLibraryErrorString(code == -1 ? errno : code); +} +#endif + +QT_END_NAMESPACE diff --git a/src/corelib/kernel/qsystemerror_p.h b/src/corelib/kernel/qsystemerror_p.h index 440b7631497..1d8c253f53b 100644 --- a/src/corelib/kernel/qsystemerror_p.h +++ b/src/corelib/kernel/qsystemerror_p.h @@ -69,10 +69,16 @@ public: inline QSystemError(int error, ErrorScope scope); inline QSystemError(); - QString toString() const; + inline QString toString() const; inline ErrorScope scope() const; inline int error() const; + static QString string(ErrorScope errorScope, int errorCode); + static QString stdString(int errorCode = -1); +#ifdef Q_OS_WIN + static QString windowsString(int errorCode = -1); +#endif + //data members int errorCode; ErrorScope errorScope; @@ -90,6 +96,11 @@ QSystemError::QSystemError() } +QString QSystemError::toString() const +{ + return string(errorScope, errorCode); +} + QSystemError::ErrorScope QSystemError::scope() const { return errorScope; @@ -100,7 +111,6 @@ int QSystemError::error() const return errorCode; } - QT_END_NAMESPACE #endif // QSYSTEMERROR_P_H diff --git a/tests/auto/tools/qmakelib/evaltest.cpp b/tests/auto/tools/qmakelib/evaltest.cpp index 4e215b85705..03fd4753fdc 100644 --- a/tests/auto/tools/qmakelib/evaltest.cpp +++ b/tests/auto/tools/qmakelib/evaltest.cpp @@ -2303,7 +2303,11 @@ void tst_qmakelib::addTestFunctions(const QString &qindir) QTest::newRow("include(): fail") << "include(include/nope.pri): OK = 1" << "OK = UNDEF" +#ifdef Q_OS_WIN + << "Cannot read " + m_indir + "/include/nope.pri: The system cannot find the file specified." +#else << "Cannot read " + m_indir + "/include/nope.pri: No such file or directory" +#endif << true; QTest::newRow("include(): silent fail") From bf410ed529789f89a63af6a35bb06837b31b95a2 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 29 Jun 2017 22:14:53 -0700 Subject: [PATCH 25/27] Convert improper uses of qt_error_string() to QSystemError::stdString() On Windows, qt_error_string() returns the string corresponding to the Win32 API, not an errno. Replace those uses for a function that works for errno values. Change-Id: I1eba2b016de74620bfc8fffd14ccce6162bafdca Reviewed-by: Lars Knoll --- src/corelib/io/qfsfileengine.cpp | 22 +++++++++++----------- src/corelib/io/qfsfileengine_win.cpp | 4 ++-- src/corelib/io/qresource.cpp | 3 ++- src/corelib/plugin/qlibrary.cpp | 3 ++- 4 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp index 0b9cd0557f9..88e8baedca4 100644 --- a/src/corelib/io/qfsfileengine.cpp +++ b/src/corelib/io/qfsfileengine.cpp @@ -268,7 +268,7 @@ bool QFSFileEnginePrivate::openFh(QIODevice::OpenMode openMode, FILE *fh) if (ret != 0) { q->setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError, - qt_error_string(int(errno))); + QSystemError::stdString()); this->openMode = QIODevice::NotOpen; this->fh = 0; @@ -332,7 +332,7 @@ bool QFSFileEnginePrivate::openFd(QIODevice::OpenMode openMode, int fd) if (ret == -1) { q->setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError, - qt_error_string(int(errno))); + QSystemError::stdString()); this->openMode = QIODevice::NotOpen; this->fd = -1; @@ -391,7 +391,7 @@ bool QFSFileEnginePrivate::closeFdFh() if (!flushed || !closed) { if (flushed) { // If not flushed, we want the flush error to fall through. - q->setError(QFile::UnspecifiedError, qt_error_string(errno)); + q->setError(QFile::UnspecifiedError, QSystemError::stdString()); } return false; } @@ -443,7 +443,7 @@ bool QFSFileEnginePrivate::flushFh() if (ret != 0) { q->setError(errno == ENOSPC ? QFile::ResourceError : QFile::WriteError, - qt_error_string(errno)); + QSystemError::stdString()); return false; } return true; @@ -539,14 +539,14 @@ bool QFSFileEnginePrivate::seekFdFh(qint64 pos) } while (ret != 0 && errno == EINTR); if (ret != 0) { - q->setError(QFile::ReadError, qt_error_string(int(errno))); + q->setError(QFile::ReadError, QSystemError::stdString()); return false; } } else { // Unbuffered stdio mode. if (QT_LSEEK(fd, QT_OFF_T(pos), SEEK_SET) == -1) { qWarning("QFile::at: Cannot set file position %lld", pos); - q->setError(QFile::PositionError, qt_error_string(errno)); + q->setError(QFile::PositionError, QSystemError::stdString()); return false; } } @@ -588,7 +588,7 @@ qint64 QFSFileEnginePrivate::readFdFh(char *data, qint64 len) Q_Q(QFSFileEngine); if (len < 0 || len != qint64(size_t(len))) { - q->setError(QFile::ReadError, qt_error_string(EINVAL)); + q->setError(QFile::ReadError, QSystemError::stdString(EINVAL)); return -1; } @@ -634,7 +634,7 @@ qint64 QFSFileEnginePrivate::readFdFh(char *data, qint64 len) if (!eof && readBytes == 0) { readBytes = -1; - q->setError(QFile::ReadError, qt_error_string(errno)); + q->setError(QFile::ReadError, QSystemError::stdString()); } return readBytes; @@ -680,7 +680,7 @@ qint64 QFSFileEnginePrivate::readLineFdFh(char *data, qint64 maxlen) // solves this. if (!fgets(data, int(maxlen + 1), fh)) { if (!feof(fh)) - q->setError(QFile::ReadError, qt_error_string(int(errno))); + q->setError(QFile::ReadError, QSystemError::stdString()); return -1; // error } @@ -719,7 +719,7 @@ qint64 QFSFileEnginePrivate::writeFdFh(const char *data, qint64 len) Q_Q(QFSFileEngine); if (len < 0 || len != qint64(size_t(len))) { - q->setError(QFile::WriteError, qt_error_string(EINVAL)); + q->setError(QFile::WriteError, QSystemError::stdString(EINVAL)); return -1; } @@ -756,7 +756,7 @@ qint64 QFSFileEnginePrivate::writeFdFh(const char *data, qint64 len) if (len && writtenBytes == 0) { writtenBytes = -1; - q->setError(errno == ENOSPC ? QFile::ResourceError : QFile::WriteError, qt_error_string(errno)); + q->setError(errno == ENOSPC ? QFile::ResourceError : QFile::WriteError, QSystemError::stdString()); } else { // reset the cached size, if any metaData.clearFlags(QFileSystemMetaData::SizeAttribute); diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index 7d16e591958..fb3cdd39818 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -252,7 +252,7 @@ qint64 QFSFileEnginePrivate::nativeSize() const filled = doStat(QFileSystemMetaData::SizeAttribute); if (!filled) { - thatQ->setError(QFile::UnspecifiedError, qt_error_string(errno)); + thatQ->setError(QFile::UnspecifiedError, QSystemError::stdString()); return 0; } return metaData.size(); @@ -319,7 +319,7 @@ qint64 QFSFileEnginePrivate::nativeRead(char *data, qint64 maxlen) if (fh || fd != -1) { // stdio / stdlib mode. if (fh && nativeIsSequential() && feof(fh)) { - q->setError(QFile::ReadError, qt_error_string(int(errno))); + q->setError(QFile::ReadError, QSystemError::stdString()); return -1; } diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp index 32639759e43..4e7120a3b8a 100644 --- a/src/corelib/io/qresource.cpp +++ b/src/corelib/io/qresource.cpp @@ -53,6 +53,7 @@ #include #include #include "private/qabstractfileengine_p.h" +#include "private/qsystemerror_p.h" #ifdef Q_OS_UNIX # include "private/qcore_unix_p.h" @@ -1284,7 +1285,7 @@ bool QResourceFileEngine::open(QIODevice::OpenMode flags) return false; d->uncompress(); if (!d->resource.isValid()) { - d->errorString = qt_error_string(ENOENT); + d->errorString = QSystemError::stdString(ENOENT); return false; } return true; diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp index 3d04d0802d3..ebad7f1751e 100644 --- a/src/corelib/plugin/qlibrary.cpp +++ b/src/corelib/plugin/qlibrary.cpp @@ -48,6 +48,7 @@ #include #include #include +#include #ifdef Q_OS_MAC # include #endif @@ -237,7 +238,7 @@ static bool findPatternUnloaded(const QString &library, QLibraryPrivate *lib) lib->errorString = file.errorString(); if (qt_debug_component()) { qWarning("%s: %s", (const char*) QFile::encodeName(library), - qPrintable(qt_error_string(errno))); + qPrintable(QSystemError::stdString())); } return false; } From f9bfc8b91cd8ea755808751ab6268e37ffd6c17a Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 7 Jul 2017 13:16:25 -0700 Subject: [PATCH 26/27] QSystemError: Make it format unknown Windows messages Can happen if we're using HRESULT from weird facilities. Change-Id: I3d10feaa2e5854ff3c01b32dbd068309e5131d1b Reviewed-by: Friedemann Kleint --- src/corelib/kernel/qsystemerror.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/corelib/kernel/qsystemerror.cpp b/src/corelib/kernel/qsystemerror.cpp index 6583838a9f7..fc825257ecb 100644 --- a/src/corelib/kernel/qsystemerror.cpp +++ b/src/corelib/kernel/qsystemerror.cpp @@ -103,6 +103,9 @@ static QString windowsErrorString(int errorCode) ret = QString::fromLatin1("The specified module could not be found."); if (ret.endsWith(QLatin1String("\r\n"))) ret.chop(2); + if (ret.isEmpty()) + ret = QString::fromLatin1("Unknown error 0x%1.") + .arg(unsigned(errorCode), 8, 16, QLatin1Char('0')); return ret; } #endif From ad3b41a06d9ba7219c79b5548c5b11698787288d Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 29 Jun 2017 12:55:54 -0700 Subject: [PATCH 27/27] QFile::rename: use the open file's ID, instead of using the file name To do that, we needed to add virtual id() in QAbstractFileEngine and override it in QFSFileEngine. It might be useful to return other types of IDs for the other file engines, but this commit does not attempt that just yet. Change-Id: I1eba2b016de74620bfc8fffd14ccafe0762b3c38 Reviewed-by: Friedemann Kleint Reviewed-by: Thiago Macieira --- src/corelib/io/qabstractfileengine.cpp | 11 +++++++++++ src/corelib/io/qabstractfileengine_p.h | 1 + src/corelib/io/qfile.cpp | 4 +++- src/corelib/io/qfilesystemengine_p.h | 2 ++ src/corelib/io/qfilesystemengine_unix.cpp | 14 ++++++++++++++ src/corelib/io/qfilesystemengine_win.cpp | 10 ++++++++-- src/corelib/io/qfsfileengine_p.h | 1 + src/corelib/io/qfsfileengine_unix.cpp | 8 ++++++++ src/corelib/io/qfsfileengine_win.cpp | 18 ++++++++++++++++++ 9 files changed, 66 insertions(+), 3 deletions(-) diff --git a/src/corelib/io/qabstractfileengine.cpp b/src/corelib/io/qabstractfileengine.cpp index 9606ec68e9c..89727673d31 100644 --- a/src/corelib/io/qabstractfileengine.cpp +++ b/src/corelib/io/qabstractfileengine.cpp @@ -677,6 +677,17 @@ bool QAbstractFileEngine::setPermissions(uint perms) return false; } +/*! + \since 5.9 + + Return an identifier that (hopefully) uniquely identifies this file in the + system. Returns an invalid QByteArray() if that cannot be calculated. +*/ +QByteArray QAbstractFileEngine::id() const +{ + return QByteArray(); +} + /*! Return the file engine's current file name in the format specified by \a file. diff --git a/src/corelib/io/qabstractfileengine_p.h b/src/corelib/io/qabstractfileengine_p.h index 48b3dec3249..58fa776e49a 100644 --- a/src/corelib/io/qabstractfileengine_p.h +++ b/src/corelib/io/qabstractfileengine_p.h @@ -141,6 +141,7 @@ public: virtual QStringList entryList(QDir::Filters filters, const QStringList &filterNames) const; virtual FileFlags fileFlags(FileFlags type=FileInfoAll) const; virtual bool setPermissions(uint perms); + virtual QByteArray id() const; virtual QString fileName(FileName file=DefaultName) const; virtual uint ownerId(FileOwner) const; virtual QString owner(FileOwner) const; diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp index a8403071452..f7e711a7cf7 100644 --- a/src/corelib/io/qfile.cpp +++ b/src/corelib/io/qfile.cpp @@ -570,7 +570,9 @@ QFile::rename(const QString &newName) // Note: this does not take file engines into account. QByteArray targetId = QFileSystemEngine::id(QFileSystemEntry(newName)); if (!targetId.isNull()) { - QByteArray fileId = QFileSystemEngine::id(QFileSystemEntry(d->fileName)); + QByteArray fileId = d->fileEngine ? + d->fileEngine->id() : + QFileSystemEngine::id(QFileSystemEntry(d->fileName)); if (fileId != targetId || d->fileName.compare(newName, Qt::CaseInsensitive)) { // ### Race condition. If a file is moved in after this, it /will/ be // overwritten. On Unix, the proper solution is to use hardlinks: diff --git a/src/corelib/io/qfilesystemengine_p.h b/src/corelib/io/qfilesystemengine_p.h index 196ed8df698..e3e52f6eaad 100644 --- a/src/corelib/io/qfilesystemengine_p.h +++ b/src/corelib/io/qfilesystemengine_p.h @@ -92,6 +92,7 @@ public: QFileSystemMetaData::MetaDataFlags what); #if defined(Q_OS_UNIX) static bool fillMetaData(int fd, QFileSystemMetaData &data); // what = PosixStatFlags + static QByteArray id(int fd); static bool setPermissions(int fd, QFile::Permissions permissions, QSystemError &error, QFileSystemMetaData *data = nullptr); #endif @@ -104,6 +105,7 @@ public: QFileSystemMetaData::MetaDataFlags what); static bool fillPermissions(const QFileSystemEntry &entry, QFileSystemMetaData &data, QFileSystemMetaData::MetaDataFlags what); + static QByteArray id(HANDLE fHandle); static QString owner(const QFileSystemEntry &entry, QAbstractFileEngine::FileOwner own); static QString nativeAbsoluteFilePath(const QString &path); #endif diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index c3906c3207e..6640e2b7e72 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -348,6 +348,20 @@ QByteArray QFileSystemEngine::id(const QFileSystemEntry &entry) return result; } +//static +QByteArray QFileSystemEngine::id(int id) +{ + QT_STATBUF statResult; + if (QT_FSTAT(id, &statResult)) { + qErrnoWarning("fstat() failed for fd %d", id); + return QByteArray(); + } + QByteArray result = QByteArray::number(quint64(statResult.st_dev), 16); + result += ':'; + result += QByteArray::number(quint64(statResult.st_ino)); + return result; +} + //static QString QFileSystemEngine::resolveUserName(uint userId) { diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index 5ed2671ab4e..1cb4c756999 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -621,13 +621,19 @@ QByteArray QFileSystemEngine::id(const QFileSystemEntry &entry) FILE_SHARE_READ, OPEN_EXISTING, NULL); #endif // Q_OS_WINRT if (handle != INVALID_HANDLE_VALUE) { - result = QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows8 ? - fileIdWin8(handle) : fileId(handle); + result = id(handle); CloseHandle(handle); } return result; } +//static +QByteArray QFileSystemEngine::id(HANDLE fHandle) +{ + return QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows8 ? + fileIdWin8(HANDLE(fHandle)) : fileId(HANDLE(fHandle)); +} + //static QString QFileSystemEngine::owner(const QFileSystemEntry &entry, QAbstractFileEngine::FileOwner own) { diff --git a/src/corelib/io/qfsfileengine_p.h b/src/corelib/io/qfsfileengine_p.h index 593ecc26871..ab9ad3aa6b7 100644 --- a/src/corelib/io/qfsfileengine_p.h +++ b/src/corelib/io/qfsfileengine_p.h @@ -93,6 +93,7 @@ public: QStringList entryList(QDir::Filters filters, const QStringList &filterNames) const Q_DECL_OVERRIDE; FileFlags fileFlags(FileFlags type) const Q_DECL_OVERRIDE; bool setPermissions(uint perms) Q_DECL_OVERRIDE; + QByteArray id() const override; QString fileName(FileName file) const Q_DECL_OVERRIDE; uint ownerId(FileOwner) const Q_DECL_OVERRIDE; QString owner(FileOwner) const Q_DECL_OVERRIDE; diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 3f4f593d811..c613368a91f 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -596,6 +596,14 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(FileFlags type) const return ret; } +QByteArray QFSFileEngine::id() const +{ + Q_D(const QFSFileEngine); + if (d->fd != -1) + return QFileSystemEngine::id(d->fd); + return QFileSystemEngine::id(d->fileEntry); +} + QString QFSFileEngine::fileName(FileName file) const { Q_D(const QFSFileEngine); diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index fb3cdd39818..7a010df671b 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -718,6 +718,24 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(QAbstractFileEngine::Fil return ret; } +QByteArray QFSFileEngine::id() const +{ + Q_D(const QFSFileEngine); + HANDLE h = d->fileHandle; + if (h == INVALID_HANDLE_VALUE) { + int localFd = d->fd; + if (d->fh && d->fileEntry.isEmpty()) + localFd = QT_FILENO(d->fh); + if (localFd != -1) + h = HANDLE(_get_osfhandle(localFd)); + } + if (h != INVALID_HANDLE_VALUE) + return QFileSystemEngine::id(h); + + // file is not open, try by path + return QFileSystemEngine::id(d->fileEntry); +} + QString QFSFileEngine::fileName(FileName file) const { Q_D(const QFSFileEngine);