diff options
author | Liang Qi <liang.qi@qt.io> | 2016-05-06 20:21:09 +0000 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2016-05-06 22:20:08 +0000 |
commit | 857912b605ea11f6f1e782edfb40555d831eb9ad (patch) | |
tree | 49a4174a44e06ba55e9253e2e7f6f45fe1764c5c | |
parent | 5aeafcea467ced35adca1d762d38bfbba2b59e1f (diff) | |
parent | dbef41f43ece97d8ac4d6b63f7a36afcb7e7b7f7 (diff) |
Merge "Merge remote-tracking branch 'origin/5.6' into 5.7" into refs/staging/5.7
94 files changed, 699 insertions, 658 deletions
diff --git a/.gitignore b/.gitignore index 1ecd8c1009..7179340e20 100644 --- a/.gitignore +++ b/.gitignore @@ -226,7 +226,6 @@ config.tests/unix/sse2/sse2 # --------------------- debug -examples/tools/plugandpaint/plugins include/* include/*/* lib/* diff --git a/examples/corelib/threads/queuedcustomtype/queuedcustomtype.pro b/examples/corelib/threads/queuedcustomtype/queuedcustomtype.pro index 77421eb638..8b91fb9ac7 100644 --- a/examples/corelib/threads/queuedcustomtype/queuedcustomtype.pro +++ b/examples/corelib/threads/queuedcustomtype/queuedcustomtype.pro @@ -8,7 +8,7 @@ SOURCES = main.cpp \ QT += widgets # install -target.path = $$[QT_INSTALL_EXAMPLES]/corelib/threads/mandelbrot +target.path = $$[QT_INSTALL_EXAMPLES]/corelib/threads/queuedcustomtype INSTALLS += target diff --git a/examples/corelib/threads/queuedcustomtype/window.h b/examples/corelib/threads/queuedcustomtype/window.h index 4dafb23c2d..c472c0fea7 100644 --- a/examples/corelib/threads/queuedcustomtype/window.h +++ b/examples/corelib/threads/queuedcustomtype/window.h @@ -54,8 +54,10 @@ #include <QWidget> #include "renderthread.h" +QT_BEGIN_NAMESPACE class QLabel; class QPushButton; +QT_END_NAMESPACE //! [Window class definition] class Window : public QWidget diff --git a/examples/corelib/threads/threads.pro b/examples/corelib/threads/threads.pro index e47da84a06..b9e17a8430 100644 --- a/examples/corelib/threads/threads.pro +++ b/examples/corelib/threads/threads.pro @@ -4,4 +4,6 @@ CONFIG += no_docs_target SUBDIRS = semaphores \ waitconditions -qtHaveModule(widgets): SUBDIRS += mandelbrot +qtHaveModule(widgets): SUBDIRS += \ + mandelbrot \ + queuedcustomtype diff --git a/examples/corelib/tools/customtype/customtype.pro b/examples/corelib/tools/customtype/customtype.pro index 1bd792db85..0e0fe9b1a5 100644 --- a/examples/corelib/tools/customtype/customtype.pro +++ b/examples/corelib/tools/customtype/customtype.pro @@ -4,5 +4,5 @@ SOURCES = main.cpp \ QT += widgets # install -target.path = $$[QT_INSTALL_EXAMPLES]/corelib/tools/customcompleter +target.path = $$[QT_INSTALL_EXAMPLES]/corelib/tools/customtype INSTALLS += target diff --git a/examples/corelib/tools/customtypesending/customtypesending.pro b/examples/corelib/tools/customtypesending/customtypesending.pro index 672f6569c2..da351ce828 100644 --- a/examples/corelib/tools/customtypesending/customtypesending.pro +++ b/examples/corelib/tools/customtypesending/customtypesending.pro @@ -6,5 +6,5 @@ SOURCES = main.cpp \ QT += widgets # install -target.path = $$[QT_INSTALL_EXAMPLES]/corelib/tools/customcompleter +target.path = $$[QT_INSTALL_EXAMPLES]/corelib/tools/customtypesending INSTALLS += target diff --git a/examples/opengl/contextinfo/contextinfo.pro b/examples/opengl/contextinfo/contextinfo.pro index ddaa084f38..2836e5ea5a 100644 --- a/examples/opengl/contextinfo/contextinfo.pro +++ b/examples/opengl/contextinfo/contextinfo.pro @@ -7,3 +7,7 @@ SOURCES += main.cpp \ HEADERS += widget.h \ renderwindow.h + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/opengl/contextinfo +INSTALLS += target diff --git a/examples/opengl/opengl.pro b/examples/opengl/opengl.pro index ed8134743b..a102e08733 100644 --- a/examples/opengl/opengl.pro +++ b/examples/opengl/opengl.pro @@ -16,3 +16,6 @@ qtHaveModule(widgets) { textures \ hellogles3 } + +EXAMPLE_FILES += \ + legacy diff --git a/examples/qtestlib/tutorial5/containers.cpp b/examples/qtestlib/tutorial5/containers.cpp deleted file mode 100644 index 43e4f101ce..0000000000 --- a/examples/qtestlib/tutorial5/containers.cpp +++ /dev/null @@ -1,274 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite 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$ -** -****************************************************************************/ -// This file contains benchmarks for comparing QVector against std::vector - -#include <QtCore> -#include <QVector> -#include <vector> - -#include <qtest.h> - -template <typename T> // T is the item type -class UseCases { -public: - virtual ~UseCases() {} - - // Use case: Insert \a size items into the vector. - virtual void insert(int size) = 0; - - // Use case: Lookup \a size items from the vector. - virtual void lookup(int size) = 0; -}; - -template <typename T> -T * f(T *ts) // dummy function to prevent code from being optimized away by the compiler -{ - return ts; -} - -// This subclass implements the use cases using QVector as efficiently as possible. -template <typename T> -class UseCases_QVector : public UseCases<T> -{ - void insert(int size) - { - QVector<T> v; - T t; - QBENCHMARK { - for (int i = 0; i < size; ++i) - v.append(t); - } - } - - void lookup(int size) - { - QVector<T> v; - - T t; - for (int i = 0; i < size; ++i) - v.append(t); - - T *ts = new T[size]; - QBENCHMARK { - for (int i = 0; i < size; ++i) - ts[i] = v.value(i); - } - f<T>(ts); - delete[] ts; - } -}; - -// This subclass implements the use cases using std::vector as efficiently as possible. -template <typename T> -class UseCases_stdvector : public UseCases<T> -{ - void insert(int size) - { - std::vector<T> v; - T t; - QBENCHMARK { - for (int i = 0; i < size; ++i) - v.push_back(t); - } - } - - void lookup(int size) - { - std::vector<T> v; - - T t; - for (int i = 0; i < size; ++i) - v.push_back(t); - - T *ts = new T[size]; - QBENCHMARK { - for (int i = 0; i < size; ++i) - ts[i] = v[i]; - } - f<T>(ts); - delete[] ts; - } -}; - -struct Large { // A "large" item type - int x[1000]; -}; - -// Symbian devices typically have limited memory -# define LARGE_MAX_SIZE 20000 - -class tst_vector_vs_std : public QObject -{ - Q_OBJECT -public: - tst_vector_vs_std() - { - useCases_QVector_int = new UseCases_QVector<int>; - useCases_stdvector_int = new UseCases_stdvector<int>; - - useCases_QVector_Large = new UseCases_QVector<Large>; - useCases_stdvector_Large = new UseCases_stdvector<Large>; - } - -private: - UseCases<int> *useCases_QVector_int; - UseCases<int> *useCases_stdvector_int; - UseCases<Large> *useCases_QVector_Large; - UseCases<Large> *useCases_stdvector_Large; - -private slots: - void insert_int_data(); - void insert_int(); - void insert_Large_data(); - void insert_Large(); - void lookup_int_data(); - void lookup_int(); - void lookup_Large_data(); - void lookup_Large(); -}; - -void tst_vector_vs_std::insert_int_data() -{ - QTest::addColumn<bool>("useStd"); - QTest::addColumn<int>("size"); - - for (int size = 10; size < 20000; size += 100) { - const QByteArray sizeString = QByteArray::number(size); - QTest::newRow(("std::vector-int--" + sizeString).constData()) << true << size; - QTest::newRow(("QVector-int--" + sizeString).constData()) << false << size; - } -} - -void tst_vector_vs_std::insert_int() -{ - QFETCH(bool, useStd); - QFETCH(int, size); - - if (useStd) - useCases_stdvector_int->insert(size); - else - useCases_QVector_int->insert(size); -} - -void tst_vector_vs_std::insert_Large_data() -{ - QTest::addColumn<bool>("useStd"); - QTest::addColumn<int>("size"); - - for (int size = 10; size < LARGE_MAX_SIZE; size += 100) { - const QByteArray sizeString = QByteArray::number(size); - QTest::newRow(("std::vector-Large--" + sizeString).constData()) << true << size; - QTest::newRow(("QVector-Large--" + sizeString).constData()) << false << size; - } -} - -void tst_vector_vs_std::insert_Large() -{ - QFETCH(bool, useStd); - QFETCH(int, size); - - if (useStd) - useCases_stdvector_Large->insert(size); - else - useCases_QVector_Large->insert(size); -} - -//! [1] -void tst_vector_vs_std::lookup_int_data() -{ - QTest::addColumn<bool>("useStd"); - QTest::addColumn<int>("size"); - - for (int size = 10; size < 20000; size += 100) { - const QByteArray sizeString = QByteArray::number(size); - QTest::newRow(("std::vector-int--" + sizeString).constData()) << true << size; - QTest::newRow(("QVector-int--" + sizeString).constData()) << false << size; - } -} -//! [1] - -//! [2] -void tst_vector_vs_std::lookup_int() -{ - QFETCH(bool, useStd); - QFETCH(int, size); - - if (useStd) - useCases_stdvector_int->lookup(size); // Create a std::vector and run the benchmark. - else - useCases_QVector_int->lookup(size); // Create a QVector and run the benchmark. -} -//! [2] - -void tst_vector_vs_std::lookup_Large_data() -{ - QTest::addColumn<bool>("useStd"); - QTest::addColumn<int>("size"); - - for (int size = 10; size < LARGE_MAX_SIZE; size += 100) { - const QByteArray sizeString = QByteArray::number(size); - QTest::newRow(("std::vector-Large--" + sizeString).constData()) << true << size; - QTest::newRow(("QVector-Large--" + sizeString).constData()) << false << size; - } -} - -void tst_vector_vs_std::lookup_Large() -{ - QFETCH(bool, useStd); - QFETCH(int, size); - - if (useStd) - useCases_stdvector_Large->lookup(size); - else - useCases_QVector_Large->lookup(size); -} - -QTEST_MAIN(tst_vector_vs_std) -#include "main.moc" diff --git a/examples/widgets/doc/src/plugandpaint.qdoc b/examples/widgets/doc/src/plugandpaint.qdoc index df2b601808..5495ae8097 100644 --- a/examples/widgets/doc/src/plugandpaint.qdoc +++ b/examples/widgets/doc/src/plugandpaint.qdoc @@ -26,7 +26,7 @@ ****************************************************************************/ /*! - \example tools/plugandpaint + \example tools/plugandpaint/app \title Plug & Paint Example \ingroup examples-widgets-tools @@ -47,8 +47,8 @@ through plugins, we recommend that you start by reading this overview, which explains how to make an application use plugins. Afterwards, you can read the - \l{tools/plugandpaintplugins/basictools}{Basic Tools} and - \l{tools/plugandpaintplugins/extrafilters}{Extra Filters} + \l{tools/plugandpaint/plugins/basictools}{Basic Tools} and + \l{tools/plugandpaint/plugins/extrafilters}{Extra Filters} overviews, which show how to implement static and dynamic plugins, respectively. @@ -74,7 +74,7 @@ in the plugins. - \snippet tools/plugandpaint/interfaces.h 0 + \snippet tools/plugandpaint/app/interfaces.h 0 The \c BrushInterface class declares four pure virtual functions. The first pure virtual function, \c brushes(), returns a list of @@ -96,7 +96,7 @@ virtual destructor. We provide the destructor to keep these compilers happy. - \snippet tools/plugandpaint/interfaces.h 1 + \snippet tools/plugandpaint/app/interfaces.h 1 The \c ShapeInterface class declares a \c shapes() function that works the same as \c{BrushInterface}'s \c brushes() function, and @@ -106,13 +106,13 @@ parent parameter can be used by the plugin to pop up a dialog asking the user to specify more information. - \snippet tools/plugandpaint/interfaces.h 2 + \snippet tools/plugandpaint/app/interfaces.h 2 The \c FilterInterface class declares a \c filters() function that returns a list of filter names, and a \c filterImage() function that applies a filter to an image. - \snippet tools/plugandpaint/interfaces.h 4 + \snippet tools/plugandpaint/app/interfaces.h 4 To make it possible to query at run-time whether a plugin implements a given interface, we must use the \c @@ -125,8 +125,8 @@ a good idea to include a version number in the string, as we did above. - The \l{tools/plugandpaintplugins/basictools}{Basic Tools} plugin - and the \l{tools/plugandpaintplugins/extrafilters}{Extra Filters} + The \l{tools/plugandpaint/plugins/basictools}{Basic Tools} plugin + and the \l{tools/plugandpaint/plugins/extrafilters}{Extra Filters} plugin shows how to derive from \c BrushInterface, \c ShapeInterface, and \c FilterInterface. @@ -144,7 +144,7 @@ \l{mainwindows/application}{Application}). Here, we'll concentrate on the parts of the code that are related to plugins. - \snippet tools/plugandpaint/mainwindow.cpp 4 + \snippet tools/plugandpaint/app/mainwindow.cpp 4 The \c loadPlugins() function is called from the \c MainWindow constructor to detect plugins and update the \uicontrol{Brush}, @@ -155,7 +155,7 @@ QObject. That QObject implements plugin interfaces using multiple inheritance. - \snippet tools/plugandpaint/mainwindow.cpp 5 + \snippet tools/plugandpaint/app/mainwindow.cpp 5 The next step is to load dynamic plugins. We initialize the \c pluginsDir member variable to refer to the \c plugins @@ -166,9 +166,9 @@ this file is usually located in a subdirectory, so we need to take this into account. - \snippet tools/plugandpaint/mainwindow.cpp 6 - \snippet tools/plugandpaint/mainwindow.cpp 7 - \snippet tools/plugandpaint/mainwindow.cpp 8 + \snippet tools/plugandpaint/app/mainwindow.cpp 6 + \snippet tools/plugandpaint/app/mainwindow.cpp 7 + \snippet tools/plugandpaint/app/mainwindow.cpp 8 We use QDir::entryList() to get a list of all files in that directory. Then we iterate over the result using \l foreach and @@ -181,12 +181,12 @@ If QPluginLoader::instance() is non-null, we add it to the menus. - \snippet tools/plugandpaint/mainwindow.cpp 9 + \snippet tools/plugandpaint/app/mainwindow.cpp 9 At the end, we enable or disable the \uicontrol{Brush}, \uicontrol{Shapes}, and \uicontrol{Filters} menus based on whether they contain any items. - \snippet tools/plugandpaint/mainwindow.cpp 10 + \snippet tools/plugandpaint/app/mainwindow.cpp 10 For each plugin (static or dynamic), we check which interfaces it implements using \l qobject_cast(). First, we try to cast the @@ -195,7 +195,7 @@ by \c brushes(). Then we do the same with the \c ShapeInterface and the \c FilterInterface. - \snippet tools/plugandpaint/mainwindow.cpp 3 + \snippet tools/plugandpaint/app/mainwindow.cpp 3 The \c aboutPlugins() slot is called on startup and can be invoked at any time through the \uicontrol{About Plugins} action. It @@ -211,7 +211,7 @@ plugin from which it comes from as the parent; this makes it convenient to get access to the plugin later. - \snippet tools/plugandpaint/mainwindow.cpp 0 + \snippet tools/plugandpaint/app/mainwindow.cpp 0 The \c changeBrush() slot is invoked when the user chooses one of the brushes from the \uicontrol{Brush} menu. We start by finding out @@ -222,7 +222,7 @@ identifying the brush. Next time the user draws on the paint area, \c PaintArea will use this brush. - \snippet tools/plugandpaint/mainwindow.cpp 1 + \snippet tools/plugandpaint/app/mainwindow.cpp 1 The \c insertShape() is invoked when the use chooses one of the shapes from the \uicontrol{Shapes} menu. We retrieve the QAction that @@ -230,7 +230,7 @@ QAction, and finally we call \c ShapeInterface::generateShape() to obtain a QPainterPath. - \snippet tools/plugandpaint/mainwindow.cpp 2 + \snippet tools/plugandpaint/app/mainwindow.cpp 2 The \c applyFilter() slot is similar: We retrieve the QAction that invoked the slot, then the \c FilterInterface associated to @@ -243,12 +243,12 @@ The \c PaintArea class contains some code that deals with \c BrushInterface, so we'll review it briefly. - \snippet tools/plugandpaint/paintarea.cpp 0 + \snippet tools/plugandpaint/app/paintarea.cpp 0 In \c setBrush(), we simply store the \c BrushInterface and the brush that are given to us by \c MainWindow. - \snippet tools/plugandpaint/paintarea.cpp 1 + \snippet tools/plugandpaint/app/paintarea.cpp 1 In the \l{QWidget::mouseMoveEvent()}{mouse move event handler}, we call the \c BrushInterface::mouseMove() function on the @@ -262,7 +262,7 @@ and a list of plugin file names. It calls \c findPlugins() to fill the QTreeWdiget with information about the plugins: - \snippet tools/plugandpaint/plugindialog.cpp 0 + \snippet tools/plugandpaint/app/plugindialog.cpp 0 The \c findPlugins() is very similar to \c MainWindow::loadPlugins(). It uses QPluginLoader to access the @@ -270,11 +270,11 @@ populateTreeWidget() uses \l qobject_cast() to find out which interfaces are implemented by the plugins: - \snippet tools/plugandpaint/plugindialog.cpp 1 + \snippet tools/plugandpaint/app/plugindialog.cpp 1 \section1 Importing Static Plugins - The \l{tools/plugandpaintplugins/basictools}{Basic Tools} plugin + The \l{tools/plugandpaint/plugins/basictools}{Basic Tools} plugin is built as a static plugin, to ensure that it is always available to the application. This requires using the Q_IMPORT_PLUGIN() macro somewhere in the application (in a \c @@ -283,7 +283,7 @@ For Plug & Paint, we have chosen to put Q_IMPORT_PLUGIN() in \c main.cpp: - \snippet tools/plugandpaint/main.cpp 0 + \snippet tools/plugandpaint/app/main.cpp 0 The argument to Q_IMPORT_PLUGIN() is the plugin name, which corresponds with the name of the class that declares metadata for the plugin with @@ -292,10 +292,10 @@ In the \c .pro file, we need to specify the static library. Here's the project file for building Plug & Paint: - \snippet tools/plugandpaint/plugandpaint.pro 0 + \snippet tools/plugandpaint/app/app.pro 0 The \c LIBS line variable specifies the library \c pnp_basictools - located in the \c ../plugandpaintplugins/basictools directory. + located in the \c ../plugandpaint/plugins/basictools directory. (Although the \c LIBS syntax has a distinct Unix flavor, \c qmake supports it on all platforms.) @@ -306,19 +306,19 @@ This completes our review of the Plug & Paint application. At this point, you might want to take a look at the - \l{tools/plugandpaintplugins/basictools}{Basic Tools} example + \l{tools/plugandpaint/plugins/basictools}{Basic Tools} example plugin. */ /*! - \example tools/plugandpaintplugins/basictools + \example tools/plugandpaint/plugins/basictools \title Plug & Paint Basic Tools Example \brief A plugin providing the basic tools for painting functionality. \image plugandpaint.png Screenshot of the Plug & Paint example The Basic Tools example is a static plugin for the - \l{tools/plugandpaint}{Plug & Paint} example. It provides a set + \l{tools/plugandpaint/app}{Plug & Paint} example. It provides a set of basic brushes, shapes, and filters. Through the Basic Tools example, we will review the four steps involved in writing a Qt plugin: @@ -332,13 +332,13 @@ \section1 Declaration of the Plugin Class - \snippet tools/plugandpaintplugins/basictools/basictoolsplugin.h 0 + \snippet tools/plugandpaint/plugins/basictools/basictoolsplugin.h 0 We start by including \c interfaces.h, which defines the plugin - interfaces for the \l{tools/plugandpaint}{Plug & Paint} + interfaces for the \l{tools/plugandpaint/app}{Plug & Paint} application. For the \c #include to work, we need to add an \c - INCLUDEPATH entry to the \c .pro file with the path to Qt's \c - examples/tools directory. + INCLUDEPATH entry to the \c .pro file with the path to the + header file. The \c BasicToolsPlugin class is a QObject subclass that implements the \c BrushInterface, the \c ShapeInterface, and the @@ -346,12 +346,12 @@ The \c Q_INTERFACES() macro is necessary to tell \l{moc}, Qt's meta-object compiler, that the base classes are plugin interfaces. Without the \c Q_INTERFACES() macro, we couldn't use - \l qobject_cast() in the \l{tools/plugandpaint}{Plug & Paint} + \l qobject_cast() in the \l{tools/plugandpaint/app}{Plug & Paint} application to detect interfaces. For an explanation for the \c Q_PLUGIN_METADATA() macro see \l {Exporting the Plugin}. - \snippet tools/plugandpaintplugins/basictools/basictoolsplugin.h 2 + \snippet tools/plugandpaint/plugins/basictools/basictoolsplugin.h 2 In the \c public section of the class, we declare all the functions from the three interfaces. @@ -361,23 +361,23 @@ Let's now review the implementation of the \c BasicToolsPlugin member functions inherited from \c BrushInterface. - \snippet tools/plugandpaintplugins/basictools/basictoolsplugin.cpp 0 + \snippet tools/plugandpaint/plugins/basictools/basictoolsplugin.cpp 0 The \c brushes() function returns a list of brushes provided by this plugin. We provide three brushes: \uicontrol{Pencil}, \uicontrol{Air Brush}, and \uicontrol{Random Letters}. - \snippet tools/plugandpaintplugins/basictools/basictoolsplugin.cpp 1 + \snippet tools/plugandpaint/plugins/basictools/basictoolsplugin.cpp 1 On a mouse press event, we just call \c mouseMove() to draw the spot where the event occurred. - \snippet tools/plugandpaintplugins/basictools/basictoolsplugin.cpp 2 + \snippet tools/plugandpaint/plugins/basictools/basictoolsplugin.cpp 2 In \c mouseMove(), we start by saving the state of the QPainter and we compute a few variables that we'll need later. - \snippet tools/plugandpaintplugins/basictools/basictoolsplugin.cpp 3 + \snippet tools/plugandpaint/plugins/basictools/basictoolsplugin.cpp 3 Then comes the brush-dependent part of the code: @@ -399,14 +399,14 @@ At the end, we restore the painter state to what it was upon entering the function and we return the bounding rectangle. - \snippet tools/plugandpaintplugins/basictools/basictoolsplugin.cpp 4 + \snippet tools/plugandpaint/plugins/basictools/basictoolsplugin.cpp 4 When the user releases the mouse, we do nothing and return an empty QRect. \section1 Implementation of the Shape Interface - \snippet tools/plugandpaintplugins/basictools/basictoolsplugin.cpp 5 + \snippet tools/plugandpaint/plugins/basictools/basictoolsplugin.cpp 5 The plugin provides three shapes: \uicontrol{Circle}, \uicontrol{Star}, and \uicontrol{Text...}. The three dots after \uicontrol{Text} are there because @@ -418,7 +418,7 @@ distinguish between the internal shape name and the name used in the user interface. - \snippet tools/plugandpaintplugins/basictools/basictoolsplugin.cpp 6 + \snippet tools/plugandpaint/plugins/basictools/basictoolsplugin.cpp 6 The \c generateShape() creates a QPainterPath for the specified shape. If the shape is \uicontrol{Text}, we pop up a QInputDialog to @@ -426,12 +426,12 @@ \section1 Implementation of the Filter Interface - \snippet tools/plugandpaintplugins/basictools/basictoolsplugin.cpp 7 + \snippet tools/plugandpaint/plugins/basictools/basictoolsplugin.cpp 7 The plugin provides three filters: \uicontrol{Invert Pixels}, \uicontrol{Swap RGB}, and \uicontrol{Grayscale}. - \snippet tools/plugandpaintplugins/basictools/basictoolsplugin.cpp 8 + \snippet tools/plugandpaint/plugins/basictools/basictoolsplugin.cpp 8 The \c filterImage() function takes a filter name and a QImage as parameters and returns an altered QImage. The first thing we do @@ -450,7 +450,7 @@ It must contain the plugins IID and optionally a filename pointing to a json file containing the metadata for the plugin. - \snippet tools/plugandpaintplugins/basictools/basictoolsplugin.h 4 + \snippet tools/plugandpaint/plugins/basictools/basictoolsplugin.h 4 Within this example the json file does not need to export any metadata, so it just contains an empty json object. @@ -463,7 +463,7 @@ Here's the project file for building the Basic Tools plugin: - \snippet tools/plugandpaintplugins/basictools/basictools.pro 0 + \snippet tools/plugandpaint/plugins/basictools/basictools.pro 0 The \c .pro file differs from typical \c .pro files in many respects. First, it starts with a \c TEMPLATE entry specifying \c @@ -475,15 +475,14 @@ To make the plugin a static plugin, all that is required is to specify \c static in addition to \c plugin. The - \l{tools/plugandpaintplugins/extrafilters}{Extra Filters} plugin, + \l{tools/plugandpaint/plugins/extrafilters}{Extra Filters} plugin, which is compiled as a dynamic plugin, doesn't specify \c static in its \c .pro file. The \c INCLUDEPATH variable sets the search paths for global headers (i.e., header files included using \c{#include <...>}). - We add Qt's \c examples/tools directory (strictly speaking, - \c{examples/tools/plugandpaintplugins/basictools/../..}) to the - list, so that we can include \c <plugandpaint/interfaces.h>. + We add \c ../../app to the list, so that we can include + \c <interfaces.h>. The \c TARGET variable specifies which name we want to give the target library. We use \c pnp_ as the prefix to show that the @@ -499,27 +498,27 @@ */ /*! - \example tools/plugandpaintplugins/extrafilters + \example tools/plugandpaint/plugins/extrafilters \title Plug & Paint Extra Filters Example \brief A plugin providing the extra filters. \image plugandpaint.png Screenshot of the Plug & Paint example The Extra Filters example is a plugin for the - \l{tools/plugandpaint}{Plug & Paint} example. It provides a set + \l{tools/plugandpaint/app}{Plug & Paint} example. It provides a set of filters in addition to those provided by the - \l{tools/plugandpaintplugins/basictools}{Basic Tools} plugin. + \l{tools/plugandpaint/plugins/basictools}{Basic Tools} plugin. Since the approach is identical to - \l{tools/plugandpaintplugins/basictools}{Basic Tools}, we won't + \l{tools/plugandpaint/plugins/basictools}{Basic Tools}, we won't review the code here. The only part of interest is the \c .pro file, since Extra Filters is a dynamic plugin - (\l{tools/plugandpaintplugins/basictools}{Basic Tools} is + (\l{tools/plugandpaint/plugins/basictools}{Basic Tools} is linked statically into the Plug & Paint executable). Here's the project file for building the Extra Filters plugin: - \snippet tools/plugandpaintplugins/extrafilters/extrafilters.pro 0 + \snippet tools/plugandpaint/plugins/extrafilters/extrafilters.pro 0 The \c .pro file differs from typical \c .pro files in many respects. First, it starts with a \c TEMPLATE entry specifying \c @@ -531,9 +530,8 @@ The \c INCLUDEPATH variable sets the search paths for global headers (i.e., header files included using \c{#include <...>}). - We add Qt's \c examples/tools directory (strictly speaking, - \c{examples/tools/plugandpaintplugins/basictools/../..}) to the - list, so that we can include \c <plugandpaint/interfaces.h>. + We add \c ../../app to the list, so that we can include + \c <interfaces.h>. The \c TARGET variable specifies which name we want to give the target library. We use \c pnp_ as the prefix to show that the diff --git a/examples/widgets/itemviews/storageview/storageview.pro b/examples/widgets/itemviews/storageview/storageview.pro index c5c01dc4f1..07e7fb5145 100644 --- a/examples/widgets/itemviews/storageview/storageview.pro +++ b/examples/widgets/itemviews/storageview/storageview.pro @@ -5,3 +5,7 @@ SOURCES += storagemodel.cpp \ main.cpp HEADERS += \ storagemodel.h + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/widgets/itemviews/storageview +INSTALLS += target diff --git a/examples/widgets/tools/echoplugin/echoplugin.pro b/examples/widgets/tools/echoplugin/echoplugin.pro index d95eb6b64a..1e3d625b2f 100644 --- a/examples/widgets/tools/echoplugin/echoplugin.pro +++ b/examples/widgets/tools/echoplugin/echoplugin.pro @@ -3,7 +3,3 @@ TEMPLATE = subdirs SUBDIRS = echowindow \ plugin #! [0] - -# install -target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tools/echoplugin -INSTALLS += target diff --git a/examples/widgets/tools/echoplugin/echowindow/echowindow.pro b/examples/widgets/tools/echoplugin/echowindow/echowindow.pro index fca0252a82..092258dd30 100644 --- a/examples/widgets/tools/echoplugin/echowindow/echowindow.pro +++ b/examples/widgets/tools/echoplugin/echowindow/echowindow.pro @@ -17,3 +17,5 @@ win32 { # install target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tools/echoplugin INSTALLS += target + +CONFIG += install_ok # Do not cargo-cult this! diff --git a/examples/widgets/tools/echoplugin/plugin/plugin.pro b/examples/widgets/tools/echoplugin/plugin/plugin.pro index 4afe56c024..a4b54b18f6 100644 --- a/examples/widgets/tools/echoplugin/plugin/plugin.pro +++ b/examples/widgets/tools/echoplugin/plugin/plugin.pro @@ -12,5 +12,7 @@ DESTDIR = ../plugins EXAMPLE_FILES = echoplugin.json # install -target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tools/echoplugin/plugin +target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tools/echoplugin/plugins INSTALLS += target + +CONFIG += install_ok # Do not cargo-cult this! diff --git a/examples/widgets/tools/plugandpaint/app/app.pro b/examples/widgets/tools/plugandpaint/app/app.pro new file mode 100644 index 0000000000..8139cd53ad --- /dev/null +++ b/examples/widgets/tools/plugandpaint/app/app.pro @@ -0,0 +1,28 @@ +#! [0] +TARGET = plugandpaint +DESTDIR = .. + +QT += widgets + +HEADERS = interfaces.h \ + mainwindow.h \ + paintarea.h \ + plugindialog.h +SOURCES = main.cpp \ + mainwindow.cpp \ + paintarea.cpp \ + plugindialog.cpp + +LIBS = -L../plugins -lpnp_basictools + +if(!debug_and_release|build_pass):CONFIG(debug, debug|release) { + mac:LIBS = $$member(LIBS, 0) $$member(LIBS, 1)_debug + win32:LIBS = $$member(LIBS, 0) $$member(LIBS, 1)d +} +#! [0] + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tools/plugandpaint +INSTALLS += target + +CONFIG += install_ok # Do not cargo-cult this! diff --git a/examples/widgets/tools/plugandpaint/interfaces.h b/examples/widgets/tools/plugandpaint/app/interfaces.h index 53f447ce87..53f447ce87 100644 --- a/examples/widgets/tools/plugandpaint/interfaces.h +++ b/examples/widgets/tools/plugandpaint/app/interfaces.h diff --git a/examples/widgets/tools/plugandpaint/main.cpp b/examples/widgets/tools/plugandpaint/app/main.cpp index f157957da5..f157957da5 100644 --- a/examples/widgets/tools/plugandpaint/main.cpp +++ b/examples/widgets/tools/plugandpaint/app/main.cpp diff --git a/examples/widgets/tools/plugandpaint/mainwindow.cpp b/examples/widgets/tools/plugandpaint/app/mainwindow.cpp index 12c65e9364..12c65e9364 100644 --- a/examples/widgets/tools/plugandpaint/mainwindow.cpp +++ b/examples/widgets/tools/plugandpaint/app/mainwindow.cpp diff --git a/examples/widgets/tools/plugandpaint/mainwindow.h b/examples/widgets/tools/plugandpaint/app/mainwindow.h index 398759fecf..398759fecf 100644 --- a/examples/widgets/tools/plugandpaint/mainwindow.h +++ b/examples/widgets/tools/plugandpaint/app/mainwindow.h diff --git a/examples/widgets/tools/plugandpaint/paintarea.cpp b/examples/widgets/tools/plugandpaint/app/paintarea.cpp index 5d2170bfd4..5d2170bfd4 100644 --- a/examples/widgets/tools/plugandpaint/paintarea.cpp +++ b/examples/widgets/tools/plugandpaint/app/paintarea.cpp diff --git a/examples/widgets/tools/plugandpaint/paintarea.h b/examples/widgets/tools/plugandpaint/app/paintarea.h index 415e4c0be4..415e4c0be4 100644 --- a/examples/widgets/tools/plugandpaint/paintarea.h +++ b/examples/widgets/tools/plugandpaint/app/paintarea.h diff --git a/examples/widgets/tools/plugandpaint/plugindialog.cpp b/examples/widgets/tools/plugandpaint/app/plugindialog.cpp index 00c2498bd5..00c2498bd5 100644 --- a/examples/widgets/tools/plugandpaint/plugindialog.cpp +++ b/examples/widgets/tools/plugandpaint/app/plugindialog.cpp diff --git a/examples/widgets/tools/plugandpaint/plugindialog.h b/examples/widgets/tools/plugandpaint/app/plugindialog.h index f8e5bcda24..f8e5bcda24 100644 --- a/examples/widgets/tools/plugandpaint/plugindialog.h +++ b/examples/widgets/tools/plugandpaint/app/plugindialog.h diff --git a/examples/widgets/tools/plugandpaint/plugandpaint.pro b/examples/widgets/tools/plugandpaint/plugandpaint.pro index 965eacf388..f7da8a52bd 100644 --- a/examples/widgets/tools/plugandpaint/plugandpaint.pro +++ b/examples/widgets/tools/plugandpaint/plugandpaint.pro @@ -1,23 +1,4 @@ -#! [0] -QT += widgets +TEMPLATE = subdirs +SUBDIRS = plugins app -HEADERS = interfaces.h \ - mainwindow.h \ - paintarea.h \ - plugindialog.h -SOURCES = main.cpp \ - mainwindow.cpp \ - paintarea.cpp \ - plugindialog.cpp - -LIBS = -Lplugins -lpnp_basictools - -if(!debug_and_release|build_pass):CONFIG(debug, debug|release) { - mac:LIBS = $$member(LIBS, 0) $$member(LIBS, 1)_debug - win32:LIBS = $$member(LIBS, 0) $$member(LIBS, 1)d -} -#! [0] - -# install -target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tools/plugandpaint -INSTALLS += target +app.depends = plugins diff --git a/examples/widgets/tools/plugandpaintplugins/basictools/basictools.json b/examples/widgets/tools/plugandpaint/plugins/basictools/basictools.json index 0967ef424b..0967ef424b 100644 --- a/examples/widgets/tools/plugandpaintplugins/basictools/basictools.json +++ b/examples/widgets/tools/plugandpaint/plugins/basictools/basictools.json diff --git a/examples/widgets/tools/plugandpaintplugins/basictools/basictools.pro b/examples/widgets/tools/plugandpaint/plugins/basictools/basictools.pro index 670ebb5709..f28be96b03 100644 --- a/examples/widgets/tools/plugandpaintplugins/basictools/basictools.pro +++ b/examples/widgets/tools/plugandpaint/plugins/basictools/basictools.pro @@ -2,13 +2,15 @@ TEMPLATE = lib CONFIG += plugin static QT += widgets -INCLUDEPATH += ../.. +INCLUDEPATH += ../../app HEADERS = basictoolsplugin.h SOURCES = basictoolsplugin.cpp TARGET = $$qtLibraryTarget(pnp_basictools) -DESTDIR = ../../plugandpaint/plugins +DESTDIR = ../../plugins #! [0] # install target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tools/plugandpaint/plugins INSTALLS += target + +CONFIG += install_ok # Do not cargo-cult this! diff --git a/examples/widgets/tools/plugandpaintplugins/basictools/basictoolsplugin.cpp b/examples/widgets/tools/plugandpaint/plugins/basictools/basictoolsplugin.cpp index c929ff6922..c929ff6922 100644 --- a/examples/widgets/tools/plugandpaintplugins/basictools/basictoolsplugin.cpp +++ b/examples/widgets/tools/plugandpaint/plugins/basictools/basictoolsplugin.cpp diff --git a/examples/widgets/tools/plugandpaintplugins/basictools/basictoolsplugin.h b/examples/widgets/tools/plugandpaint/plugins/basictools/basictoolsplugin.h index 2c159d3e37..6e6d639d12 100644 --- a/examples/widgets/tools/plugandpaintplugins/basictools/basictoolsplugin.h +++ b/examples/widgets/tools/plugandpaint/plugins/basictools/basictoolsplugin.h @@ -51,6 +51,9 @@ #ifndef BASICTOOLSPLUGIN_H #define BASICTOOLSPLUGIN_H +//! [0] +#include <interfaces.h> + #include <QRect> #include <QObject> #include <QtPlugin> @@ -58,9 +61,6 @@ #include <QPainterPath> #include <QImage> -//! [0] -#include <plugandpaint/interfaces.h> - //! [1] class BasicToolsPlugin : public QObject, public BrushInterface, diff --git a/examples/widgets/tools/plugandpaintplugins/extrafilters/extrafilters.json b/examples/widgets/tools/plugandpaint/plugins/extrafilters/extrafilters.json index 0967ef424b..0967ef424b 100644 --- a/examples/widgets/tools/plugandpaintplugins/extrafilters/extrafilters.json +++ b/examples/widgets/tools/plugandpaint/plugins/extrafilters/extrafilters.json diff --git a/examples/widgets/tools/plugandpaintplugins/extrafilters/extrafilters.pro b/examples/widgets/tools/plugandpaint/plugins/extrafilters/extrafilters.pro index aa0ead87bc..deb3c5e70e 100644 --- a/examples/widgets/tools/plugandpaintplugins/extrafilters/extrafilters.pro +++ b/examples/widgets/tools/plugandpaint/plugins/extrafilters/extrafilters.pro @@ -2,13 +2,15 @@ TEMPLATE = lib CONFIG += plugin QT += widgets -INCLUDEPATH += ../.. +INCLUDEPATH += ../../app HEADERS = extrafiltersplugin.h SOURCES = extrafiltersplugin.cpp TARGET = $$qtLibraryTarget(pnp_extrafilters) -DESTDIR = ../../plugandpaint/plugins +DESTDIR = ../../plugins #! [0] # install target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tools/plugandpaint/plugins INSTALLS += target + +CONFIG += install_ok # Do not cargo-cult this! diff --git a/examples/widgets/tools/plugandpaintplugins/extrafilters/extrafiltersplugin.cpp b/examples/widgets/tools/plugandpaint/plugins/extrafilters/extrafiltersplugin.cpp index 8f59afa759..8f59afa759 100644 --- a/examples/widgets/tools/plugandpaintplugins/extrafilters/extrafiltersplugin.cpp +++ b/examples/widgets/tools/plugandpaint/plugins/extrafilters/extrafiltersplugin.cpp diff --git a/examples/widgets/tools/plugandpaintplugins/extrafilters/extrafiltersplugin.h b/examples/widgets/tools/plugandpaint/plugins/extrafilters/extrafiltersplugin.h index b4cc02fb55..4beac9a7fb 100644 --- a/examples/widgets/tools/plugandpaintplugins/extrafilters/extrafiltersplugin.h +++ b/examples/widgets/tools/plugandpaint/plugins/extrafilters/extrafiltersplugin.h @@ -52,13 +52,13 @@ #define EXTRAFILTERSPLUGIN_H //! [0] +#include <interfaces.h> + #include <QObject> #include <QtPlugin> #include <QStringList> #include <QImage> -#include <plugandpaint/interfaces.h> - class ExtraFiltersPlugin : public QObject, public FilterInterface { Q_OBJECT diff --git a/examples/widgets/tools/plugandpaintplugins/plugandpaintplugins.pro b/examples/widgets/tools/plugandpaint/plugins/plugins.pro index e15220c621..e15220c621 100644 --- a/examples/widgets/tools/plugandpaintplugins/plugandpaintplugins.pro +++ b/examples/widgets/tools/plugandpaint/plugins/plugins.pro diff --git a/examples/widgets/tools/styleplugin/plugin/plugin.pro b/examples/widgets/tools/styleplugin/plugin/plugin.pro index c7e8de6ee2..35184fc82a 100644 --- a/examples/widgets/tools/styleplugin/plugin/plugin.pro +++ b/examples/widgets/tools/styleplugin/plugin/plugin.pro @@ -20,3 +20,5 @@ EXAMPLE_FILES += simplestyle.json # install target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tools/styleplugin/styles INSTALLS += target + +CONFIG += install_ok # Do not cargo-cult this! diff --git a/examples/widgets/tools/styleplugin/styleplugin.pro b/examples/widgets/tools/styleplugin/styleplugin.pro index b9f251116d..4f120637b0 100644 --- a/examples/widgets/tools/styleplugin/styleplugin.pro +++ b/examples/widgets/tools/styleplugin/styleplugin.pro @@ -1,7 +1,3 @@ TEMPLATE = subdirs SUBDIRS = stylewindow \ plugin - -# install -target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tools/styleplugin -INSTALLS += target diff --git a/examples/widgets/tools/styleplugin/stylewindow/stylewindow.pro b/examples/widgets/tools/styleplugin/stylewindow/stylewindow.pro index 56aa373b0e..cdc1bd2fda 100644 --- a/examples/widgets/tools/styleplugin/stylewindow/stylewindow.pro +++ b/examples/widgets/tools/styleplugin/stylewindow/stylewindow.pro @@ -15,3 +15,5 @@ win32 { # install target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tools/styleplugin INSTALLS += target + +CONFIG += install_ok # Do not cargo-cult this! diff --git a/examples/widgets/tools/tools.pro b/examples/widgets/tools/tools.pro index 503efa8403..f3cbd73d98 100644 --- a/examples/widgets/tools/tools.pro +++ b/examples/widgets/tools/tools.pro @@ -5,7 +5,6 @@ SUBDIRS = \ customcompleter \ echoplugin \ i18n \ - plugandpaintplugins \ plugandpaint \ regexp \ regularexpression \ @@ -17,12 +16,9 @@ SUBDIRS = \ contains(DEFINES, QT_NO_TRANSLATION): SUBDIRS -= i18n -plugandpaint.depends = plugandpaintplugins - load(qfeatures) contains(QT_DISABLED_FEATURES, library) { SUBDIRS -= \ echoplugin \ - plugandpaintplugins \ plugandpaint } diff --git a/mkspecs/features/file_copies.prf b/mkspecs/features/file_copies.prf index f679129e03..6df294212c 100644 --- a/mkspecs/features/file_copies.prf +++ b/mkspecs/features/file_copies.prf @@ -18,13 +18,24 @@ defineReplace(qtStripProPwd) { for (cp, COPIES) { isEmpty($${cp}.files): next() pfx = copy_$${cp} - for (f, $${cp}.files): \ - $${pfx}.files += $$absolute_path($$f, $$_PRO_FILE_PWD_) + notdir = false + dir = false + for (f, $${cp}.files) { + fil = $$absolute_path($$f, $$_PRO_FILE_PWD_) + tfiles = $$files($$fil/*) + isEmpty(tfiles): \ + notdir = true + else: \ + dir = true + $${pfx}.files += $$fil + } + $$dir:$$notdir: \ + error("COPIES entry $$cp lists both files and directories.") path = $$eval($${cp}.path) - isEmpty(path): error("COPY $cp defines no .path") + isEmpty(path): error("COPIES entry $$cp defines no .path") base = $$eval($${cp}.base) isEmpty(base) { - $${pfx}.output = $$path/${QMAKE_FILE_BASE}${QMAKE_FILE_EXT} + $${pfx}.output = $$path/${QMAKE_FILE_IN_NAME} } else: isEqual(base, $$_PRO_FILE_PWD_) { $${pfx}.output = $$path/${QMAKE_FUNC_FILE_IN_qtStripProPwd} } else { @@ -34,7 +45,12 @@ for (cp, COPIES) { $${pfx}.output = $$path/${QMAKE_FUNC_FILE_IN_qtStripSrcDir_$$cp} } $${pfx}.input = $${pfx}.files - $${pfx}.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT} + !$$dir: \ + $${pfx}.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT_PATH} + else: !copy_dir_files: \ + $${pfx}.commands = $$QMAKE_COPY_DIR ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT_PATH} + else: \ + $${pfx}.commands = $$QMAKE_COPY_DIR ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT} $${pfx}.name = COPY ${QMAKE_FILE_IN} $${pfx}.CONFIG = no_link no_clean target_predeps QMAKE_EXTRA_COMPILERS += $${pfx} diff --git a/mkspecs/features/qml_module.prf b/mkspecs/features/qml_module.prf index 6b3ad81953..05f97a5532 100644 --- a/mkspecs/features/qml_module.prf +++ b/mkspecs/features/qml_module.prf @@ -18,9 +18,6 @@ fq_qml_files = $$qmldir_file for(qmlf, QML_FILES): fq_qml_files += $$absolute_path($$qmlf, $$_PRO_FILE_PWD_) -# Only for Qt Creator's project view -OTHER_FILES += $$fq_qml_files - qml1_target: \ instbase = $$[QT_INSTALL_IMPORTS] else: \ diff --git a/mkspecs/features/qt_example_installs.prf b/mkspecs/features/qt_example_installs.prf index a644904981..ebf68a8a21 100644 --- a/mkspecs/features/qt_example_installs.prf +++ b/mkspecs/features/qt_example_installs.prf @@ -47,8 +47,13 @@ probase = $$relative_path($$_PRO_FILE_PWD_, $$dirname(_QMAKE_CONF_)/examples) sourcefiles += $$resrc } } + sourcefiles += \ + $$ANDROID_PACKAGE_SOURCE_DIR \ + $$QMAKE_INFO_PLIST \ + $$DISTFILES extras = \ $$_PRO_FILE_PWD_/README \ + $$_PRO_FILE_PWD_/README.TXT \ $$files($$_PRO_FILE_PWD_/*.pri) \ $$replace(_PRO_FILE_, \\.pro$, .qmlproject) \ $$replace(_PRO_FILE_, \\.pro$, .json) \ diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index dffc3d6acb..12004c62c3 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -1612,7 +1612,7 @@ MakefileGenerator::replaceExtraCompilerVariables( const ProKey funcname = var.mid(19).toKey(); val += project->expand(funcname, QList<ProStringList>() << ProStringList(in)); } else if(var == QLatin1String("QMAKE_FILE_BASE") || var == QLatin1String("QMAKE_FILE_IN_BASE")) { - //filePath = true; + filePath = true; for(int i = 0; i < in.size(); ++i) { QFileInfo fi(fileInfo(Option::normalizePath(in.at(i)))); QString base = fi.completeBaseName(); @@ -1620,7 +1620,7 @@ MakefileGenerator::replaceExtraCompilerVariables( base = fi.fileName(); val += base; } - } else if(var == QLatin1String("QMAKE_FILE_EXT")) { + } else if (var == QLatin1String("QMAKE_FILE_EXT") || var == QLatin1String("QMAKE_FILE_IN_EXT")) { filePath = true; for(int i = 0; i < in.size(); ++i) { QFileInfo fi(fileInfo(Option::normalizePath(in.at(i)))); @@ -1633,6 +1633,10 @@ MakefileGenerator::replaceExtraCompilerVariables( ext = fi.fileName().remove(0, baseLen); val += ext; } + } else if (var == QLatin1String("QMAKE_FILE_IN_NAME")) { + filePath = true; + for (int i = 0; i < in.size(); ++i) + val += fileInfo(Option::normalizePath(in.at(i))).fileName(); } else if(var == QLatin1String("QMAKE_FILE_PATH") || var == QLatin1String("QMAKE_FILE_IN_PATH")) { filePath = true; for(int i = 0; i < in.size(); ++i) @@ -1649,12 +1653,16 @@ MakefileGenerator::replaceExtraCompilerVariables( filePath = true; const ProKey funcname = var.mid(20).toKey(); val += project->expand(funcname, QList<ProStringList>() << ProStringList(out)); + } else if (var == QLatin1String("QMAKE_FILE_OUT_PATH")) { + filePath = true; + for (int i = 0; i < out.size(); ++i) + val += fileInfo(Option::normalizePath(out.at(i))).path(); } else if(var == QLatin1String("QMAKE_FILE_OUT")) { filePath = true; for(int i = 0; i < out.size(); ++i) val += fileInfo(Option::normalizePath(out.at(i))).filePath(); } else if(var == QLatin1String("QMAKE_FILE_OUT_BASE")) { - //filePath = true; + filePath = true; for(int i = 0; i < out.size(); ++i) { QFileInfo fi(fileInfo(Option::normalizePath(out.at(i)))); QString base = fi.completeBaseName(); diff --git a/src/concurrent/doc/snippets/code/src_concurrent_qtconcurrentmap.cpp b/src/concurrent/doc/snippets/code/src_concurrent_qtconcurrentmap.cpp index 277cbbcc5e..91e76be0db 100644 --- a/src/concurrent/doc/snippets/code/src_concurrent_qtconcurrentmap.cpp +++ b/src/concurrent/doc/snippets/code/src_concurrent_qtconcurrentmap.cpp @@ -170,7 +170,7 @@ QImage scaledToWith(const QImage &image) //! [13] QList<QImage> images = ...; -QFuture<QImage> thumbnails = QtConcurrent::mapped(images, std::bind(&QImage::scaledToWidth, 100 Qt::SmoothTransformation)); +QFuture<QImage> thumbnails = QtConcurrent::mapped(images, std::bind(&QImage::scaledToWidth, 100, Qt::SmoothTransformation)); //! [13] //! [14] diff --git a/src/corelib/global/qglobalstatic.h b/src/corelib/global/qglobalstatic.h index 4fb3c4f91f..7a6dea9b92 100644 --- a/src/corelib/global/qglobalstatic.h +++ b/src/corelib/global/qglobalstatic.h @@ -116,7 +116,7 @@ QT_BEGIN_NAMESPACE guard.store(QtGlobalStatic::Destroyed); \ } \ } cleanup; \ - guard.store(QtGlobalStatic::Initialized); \ + guard.storeRelease(QtGlobalStatic::Initialized); \ } \ } \ return d; \ diff --git a/src/corelib/io/qfilesystemengine.cpp b/src/corelib/io/qfilesystemengine.cpp index 2dad56befd..fd8f251ccb 100644 --- a/src/corelib/io/qfilesystemengine.cpp +++ b/src/corelib/io/qfilesystemengine.cpp @@ -264,7 +264,7 @@ void QFileSystemMetaData::fillFromStatBuf(const QT_STATBUF &statBuffer) entryFlags |= QFileSystemMetaData::FileType; else if ((statBuffer.st_mode & S_IFMT) == S_IFDIR) entryFlags |= QFileSystemMetaData::DirectoryType; - else + else if ((statBuffer.st_mode & S_IFMT) != S_IFBLK) entryFlags |= QFileSystemMetaData::SequentialType; // Attributes @@ -347,6 +347,18 @@ void QFileSystemMetaData::fillFromDirEnt(const QT_DIRENT &entry) break; case DT_BLK: + knownFlagsMask = QFileSystemMetaData::LinkType + | QFileSystemMetaData::FileType + | QFileSystemMetaData::DirectoryType + | QFileSystemMetaData::BundleType + | QFileSystemMetaData::AliasType + | QFileSystemMetaData::SequentialType + | QFileSystemMetaData::ExistsAttribute; + + entryFlags = QFileSystemMetaData::ExistsAttribute; + + break; + case DT_CHR: case DT_FIFO: case DT_SOCK: diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index 0829bbc6e8..115b31dd2e 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -1422,8 +1422,9 @@ bool QFileSystemEngine::copyFile(const QFileSystemEntry &source, const QFileSyst COPYFILE2_EXTENDED_PARAMETERS copyParams = { sizeof(copyParams), COPY_FILE_FAIL_IF_EXISTS, NULL, NULL, NULL }; - bool ret = ::CopyFile2((const wchar_t*)source.nativeFilePath().utf16(), - (const wchar_t*)target.nativeFilePath().utf16(), ©Params) != 0; + HRESULT hres = ::CopyFile2((const wchar_t*)source.nativeFilePath().utf16(), + (const wchar_t*)target.nativeFilePath().utf16(), ©Params); + bool ret = SUCCEEDED(hres); #endif // Q_OS_WINRT if(!ret) error = QSystemError(::GetLastError(), QSystemError::NativeError); diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index 854db31a79..a9d3e0bfe8 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -1103,7 +1103,6 @@ bool QProcessPrivate::_q_canReadStandardError() */ bool QProcessPrivate::_q_canWrite() { - Q_Q(QProcess); if (stdinChannel.notifier) stdinChannel.notifier->setEnabled(false); @@ -1114,31 +1113,13 @@ bool QProcessPrivate::_q_canWrite() return false; } - qint64 written = writeToStdin(writeBuffer.readPointer(), writeBuffer.nextDataBlockSize()); - if (written < 0) { - closeChannel(&stdinChannel); - setErrorAndEmit(QProcess::WriteError); - return false; - } + const bool writeSucceeded = writeToStdin(); -#if defined QPROCESS_DEBUG - qDebug("QProcessPrivate::canWrite(), wrote %d bytes to the process input", int(written)); -#endif - - if (written != 0) { - writeBuffer.free(written); - if (!emittedBytesWritten) { - emittedBytesWritten = true; - emit q->bytesWritten(written); - emittedBytesWritten = false; - } - emit q->channelBytesWritten(0, written); - } if (stdinChannel.notifier && !writeBuffer.isEmpty()) stdinChannel.notifier->setEnabled(true); if (writeBuffer.isEmpty() && stdinChannel.closed) closeWriteChannel(); - return true; + return writeSucceeded; } /*! diff --git a/src/corelib/io/qprocess_p.h b/src/corelib/io/qprocess_p.h index 1f88c3a043..ae236c8c60 100644 --- a/src/corelib/io/qprocess_p.h +++ b/src/corelib/io/qprocess_p.h @@ -379,7 +379,7 @@ public: qint64 bytesAvailableInChannel(const Channel *channel) const; qint64 readFromChannel(const Channel *channel, char *data, qint64 maxlen); - qint64 writeToStdin(const char *data, qint64 maxlen); + bool writeToStdin(); void cleanup(); void setError(QProcess::ProcessError error, const QString &description = QString()); diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp index a5b7692fc9..8c5589538d 100644 --- a/src/corelib/io/qprocess_unix.cpp +++ b/src/corelib/io/qprocess_unix.cpp @@ -681,21 +681,36 @@ qint64 QProcessPrivate::readFromChannel(const Channel *channel, char *data, qint return bytesRead; } -qint64 QProcessPrivate::writeToStdin(const char *data, qint64 maxlen) +bool QProcessPrivate::writeToStdin() { - qint64 written = qt_safe_write_nosignal(stdinChannel.pipe[1], data, maxlen); + const char *data = writeBuffer.readPointer(); + const qint64 bytesToWrite = writeBuffer.nextDataBlockSize(); + + qint64 written = qt_safe_write_nosignal(stdinChannel.pipe[1], data, bytesToWrite); #if defined QPROCESS_DEBUG - qDebug("QProcessPrivate::writeToStdin(%p \"%s\", %lld) == %lld", - data, qt_prettyDebug(data, maxlen, 16).constData(), maxlen, written); + qDebug("QProcessPrivate::writeToStdin(), write(%p \"%s\", %lld) == %lld", + data, qt_prettyDebug(data, bytesToWrite, 16).constData(), bytesToWrite, written); if (written == -1) qDebug("QProcessPrivate::writeToStdin(), failed to write (%s)", qPrintable(qt_error_string(errno))); #endif - // If the O_NONBLOCK flag is set and If some data can be written without blocking - // the process, write() will transfer what it can and return the number of bytes written. - // Otherwise, it will return -1 and set errno to EAGAIN - if (written == -1 && errno == EAGAIN) - written = 0; - return written; + if (written == -1) { + // If the O_NONBLOCK flag is set and If some data can be written without blocking + // the process, write() will transfer what it can and return the number of bytes written. + // Otherwise, it will return -1 and set errno to EAGAIN + if (errno == EAGAIN) + return true; + + closeChannel(&stdinChannel); + setErrorAndEmit(QProcess::WriteError); + return false; + } + writeBuffer.free(written); + if (!emittedBytesWritten && written != 0) { + emittedBytesWritten = true; + emit q_func()->bytesWritten(written); + emittedBytesWritten = false; + } + return true; } void QProcessPrivate::terminateProcess() diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp index ed540f9e5b..96b39efe3a 100644 --- a/src/corelib/io/qprocess_win.cpp +++ b/src/corelib/io/qprocess_win.cpp @@ -805,17 +805,23 @@ qint64 QProcessPrivate::pipeWriterBytesToWrite() const return stdinChannel.writer ? stdinChannel.writer->bytesToWrite() : qint64(0); } -qint64 QProcessPrivate::writeToStdin(const char *data, qint64 maxlen) +bool QProcessPrivate::writeToStdin() { Q_Q(QProcess); if (!stdinChannel.writer) { stdinChannel.writer = new QWindowsPipeWriter(stdinChannel.pipe[1], q); + QObject::connect(stdinChannel.writer, &QWindowsPipeWriter::bytesWritten, + q, &QProcess::bytesWritten); QObjectPrivate::connect(stdinChannel.writer, &QWindowsPipeWriter::canWrite, this, &QProcessPrivate::_q_canWrite); + } else { + if (stdinChannel.writer->isWriteOperationActive()) + return true; } - return stdinChannel.writer->write(data, maxlen); + stdinChannel.writer->write(writeBuffer.read()); + return true; } // Use ShellExecuteEx() to trigger an UAC prompt when CreateProcess()fails diff --git a/src/corelib/io/qprocess_wince.cpp b/src/corelib/io/qprocess_wince.cpp index 564b3f520d..824a6158dc 100644 --- a/src/corelib/io/qprocess_wince.cpp +++ b/src/corelib/io/qprocess_wince.cpp @@ -271,11 +271,9 @@ qint64 QProcessPrivate::pipeWriterBytesToWrite() const return 0; } -qint64 QProcessPrivate::writeToStdin(const char *data, qint64 maxlen) +bool QProcessPrivate::writeToStdin() { - Q_UNUSED(data); - Q_UNUSED(maxlen); - return -1; + return false; } bool QProcessPrivate::startDetached(const QString &program, const QStringList &arguments, const QString &workingDir, qint64 *pid) diff --git a/src/corelib/io/qwindowspipewriter.cpp b/src/corelib/io/qwindowspipewriter.cpp index 79e7d13eb5..ab179641f8 100644 --- a/src/corelib/io/qwindowspipewriter.cpp +++ b/src/corelib/io/qwindowspipewriter.cpp @@ -79,21 +79,19 @@ QWindowsPipeWriter::~QWindowsPipeWriter() bool QWindowsPipeWriter::waitForWrite(int msecs) { - if (!writeSequenceStarted) - return false; - if (bytesWrittenPending) { - if (!inBytesWritten) - emitPendingBytesWrittenValue(); + emitPendingBytesWrittenValue(); return true; } + if (!writeSequenceStarted) + return false; + if (!waitForNotification(msecs)) return false; if (bytesWrittenPending) { - if (!inBytesWritten) - emitPendingBytesWrittenValue(); + emitPendingBytesWrittenValue(); return true; } @@ -102,20 +100,24 @@ bool QWindowsPipeWriter::waitForWrite(int msecs) qint64 QWindowsPipeWriter::bytesToWrite() const { - return numberOfBytesToWrite; + return numberOfBytesToWrite + pendingBytesWrittenValue; } void QWindowsPipeWriter::emitPendingBytesWrittenValue() { if (bytesWrittenPending) { + // Reset the state even if we don't emit bytesWritten(). + // It's a defined behavior to not re-emit this signal recursively. bytesWrittenPending = false; const qint64 bytes = pendingBytesWrittenValue; pendingBytesWrittenValue = 0; - inBytesWritten = true; - emit bytesWritten(bytes); - inBytesWritten = false; emit canWrite(); + if (!inBytesWritten) { + inBytesWritten = true; + emit bytesWritten(bytes); + inBytesWritten = false; + } } } @@ -135,6 +137,8 @@ void QWindowsPipeWriter::notified(DWORD errorCode, DWORD numberOfBytesWritten) notifiedCalled = true; writeSequenceStarted = false; numberOfBytesToWrite = 0; + Q_ASSERT(errorCode != ERROR_SUCCESS || numberOfBytesWritten == DWORD(buffer.size())); + buffer.clear(); switch (errorCode) { case ERROR_SUCCESS: @@ -179,21 +183,26 @@ bool QWindowsPipeWriter::waitForNotification(int timeout) return notifiedCalled; } -qint64 QWindowsPipeWriter::write(const char *ptr, qint64 maxlen) +bool QWindowsPipeWriter::write(const QByteArray &ba) { if (writeSequenceStarted) - return 0; + return false; overlapped.clear(); - numberOfBytesToWrite = maxlen; + buffer = ba; + numberOfBytesToWrite = buffer.size(); stopped = false; writeSequenceStarted = true; - if (!WriteFileEx(handle, ptr, maxlen, &overlapped, &writeFileCompleted)) { + if (!WriteFileEx(handle, buffer.constData(), numberOfBytesToWrite, + &overlapped, &writeFileCompleted)) { writeSequenceStarted = false; + numberOfBytesToWrite = 0; + buffer.clear(); qErrnoWarning("QWindowsPipeWriter::write failed."); + return false; } - return maxlen; + return true; } void QWindowsPipeWriter::stop() diff --git a/src/corelib/io/qwindowspipewriter_p.h b/src/corelib/io/qwindowspipewriter_p.h index 59f20edae0..3c641670b6 100644 --- a/src/corelib/io/qwindowspipewriter_p.h +++ b/src/corelib/io/qwindowspipewriter_p.h @@ -53,6 +53,7 @@ #include <qelapsedtimer.h> #include <qobject.h> +#include <qbytearray.h> #include <qt_windows.h> QT_BEGIN_NAMESPACE @@ -112,7 +113,7 @@ public: explicit QWindowsPipeWriter(HANDLE pipeWriteEnd, QObject *parent = 0); ~QWindowsPipeWriter(); - qint64 write(const char *data, qint64 maxlen); + bool write(const QByteArray &ba); void stop(); bool waitForWrite(int msecs); bool isWriteOperationActive() const { return writeSequenceStarted; } @@ -142,6 +143,7 @@ private: HANDLE handle; Overlapped overlapped; + QByteArray buffer; qint64 numberOfBytesToWrite; qint64 pendingBytesWrittenValue; bool stopped; diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 04ec713522..9b421d6a78 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -1130,7 +1130,7 @@ QObjectPrivate::Connection::~Connection() RTTI support and it works across dynamic library boundaries. qobject_cast() can also be used in conjunction with interfaces; - see the \l{tools/plugandpaint}{Plug & Paint} example for details. + see the \l{tools/plugandpaint/app}{Plug & Paint} example for details. \warning If T isn't declared with the Q_OBJECT macro, this function's return value is undefined. @@ -4160,11 +4160,11 @@ QDebug operator<<(QDebug dbg, const QObject *o) Example: - \snippet ../widgets/tools/plugandpaintplugins/basictools/basictoolsplugin.h 1 + \snippet ../widgets/tools/plugandpaint/plugins/basictools/basictoolsplugin.h 1 \dots - \snippet ../widgets/tools/plugandpaintplugins/basictools/basictoolsplugin.h 3 + \snippet ../widgets/tools/plugandpaint/plugins/basictools/basictoolsplugin.h 3 - See the \l{tools/plugandpaintplugins/basictools}{Plug & Paint + See the \l{tools/plugandpaint/plugins/basictools}{Plug & Paint Basic Tools} example for details. \sa Q_DECLARE_INTERFACE(), Q_PLUGIN_METADATA(), {How to Create Qt Plugins} diff --git a/src/corelib/plugin/qplugin.qdoc b/src/corelib/plugin/qplugin.qdoc index 5dcc14b64b..968fb4820a 100644 --- a/src/corelib/plugin/qplugin.qdoc +++ b/src/corelib/plugin/qplugin.qdoc @@ -44,11 +44,11 @@ to the interface class called \a ClassName. The \a Identifier must be unique. For example: - \snippet plugandpaint/interfaces.h 3 + \snippet plugandpaint/app/interfaces.h 3 This macro is normally used right after the class definition for \a ClassName, in a header file. See the - \l{tools/plugandpaint}{Plug & Paint} example for details. + \l{tools/plugandpaint/app}{Plug & Paint} example for details. If you want to use Q_DECLARE_INTERFACE with interface classes declared in a namespace then you have to make sure the Q_DECLARE_INTERFACE @@ -76,7 +76,7 @@ \snippet code/doc_src_qplugin.cpp 1 - See the \l{tools/plugandpaint}{Plug & Paint} example for details. + See the \l{tools/plugandpaint/app}{Plug & Paint} example for details. Note that the class this macro appears on must be default-constructible. diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp index 8a797772fc..4aac24f454 100644 --- a/src/corelib/thread/qthread.cpp +++ b/src/corelib/thread/qthread.cpp @@ -149,16 +149,12 @@ QThreadPrivate::QThreadPrivate(QThreadData *d) exited(false), returnCode(-1), stackSize(0), priority(QThread::InheritPriority), data(d) { -#if defined (Q_OS_UNIX) - thread_id = 0; -#elif defined (Q_OS_WIN) +#if defined (Q_OS_WIN) handle = 0; # ifndef Q_OS_WINRT id = 0; # endif waiters = 0; -#endif -#if defined (Q_OS_WIN) terminationEnabled = true; terminatePending = false; #endif diff --git a/src/corelib/thread/qthread_p.h b/src/corelib/thread/qthread_p.h index adcd98b609..37eca9c612 100644 --- a/src/corelib/thread/qthread_p.h +++ b/src/corelib/thread/qthread_p.h @@ -176,7 +176,6 @@ public: static QThread *threadForId(int id); #ifdef Q_OS_UNIX - pthread_t thread_id; QWaitCondition thread_done; static void *start(void *arg); diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp index f456e56a9c..e7a31e0b70 100644 --- a/src/corelib/thread/qthread_unix.cpp +++ b/src/corelib/thread/qthread_unix.cpp @@ -110,6 +110,8 @@ QT_BEGIN_NAMESPACE #ifndef QT_NO_THREAD +Q_STATIC_ASSERT(sizeof(pthread_t) == sizeof(Qt::HANDLE)); + enum { ThreadPriorityResetFlag = 0x80000000 }; #if defined(Q_OS_LINUX) && defined(__GLIBC__) && (defined(Q_CC_GNU) || defined(Q_CC_INTEL)) && !defined(QT_LINUXBASE) @@ -239,8 +241,6 @@ QThreadData *QThreadData::current(bool createIfNecessary) void QAdoptedThread::init() { - Q_D(QThread); - d->thread_id = pthread_self(); } /* @@ -328,10 +328,11 @@ void *QThreadPrivate::start(void *arg) // sets the name of the current thread. QString objectName = thr->objectName(); + pthread_t thread_id = reinterpret_cast<pthread_t>(data->threadId); if (Q_LIKELY(objectName.isEmpty())) - setCurrentThreadName(thr->d_func()->thread_id, thr->metaObject()->className()); + setCurrentThreadName(thread_id, thr->metaObject()->className()); else - setCurrentThreadName(thr->d_func()->thread_id, objectName.toLocal8Bit()); + setCurrentThreadName(thread_id, objectName.toLocal8Bit()); } #endif @@ -372,7 +373,6 @@ void QThreadPrivate::finish(void *arg) locker.relock(); } - d->thread_id = 0; d->running = false; d->finished = true; d->interruptionRequested = false; @@ -618,15 +618,16 @@ void QThread::start(Priority priority) } int code = - pthread_create(&d->thread_id, &attr, QThreadPrivate::start, this); + pthread_create(reinterpret_cast<pthread_t *>(&d->data->threadId), &attr, + QThreadPrivate::start, this); if (code == EPERM) { // caller does not have permission to set the scheduling // parameters/policy #if defined(QT_HAS_THREAD_PRIORITY_SCHEDULING) pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED); #endif - code = - pthread_create(&d->thread_id, &attr, QThreadPrivate::start, this); + code = pthread_create(reinterpret_cast<pthread_t *>(&d->data->threadId), &attr, + QThreadPrivate::start, this); } pthread_attr_destroy(&attr); @@ -636,7 +637,7 @@ void QThread::start(Priority priority) d->running = false; d->finished = false; - d->thread_id = 0; + d->data->threadId = 0; } } @@ -646,10 +647,10 @@ void QThread::terminate() Q_D(QThread); QMutexLocker locker(&d->mutex); - if (!d->thread_id) + if (!d->data->threadId) return; - int code = pthread_cancel(d->thread_id); + int code = pthread_cancel(reinterpret_cast<pthread_t>(d->data->threadId)); if (code) { qWarning("QThread::start: Thread termination error: %s", qPrintable(qt_error_string((code)))); @@ -662,7 +663,7 @@ bool QThread::wait(unsigned long time) Q_D(QThread); QMutexLocker locker(&d->mutex); - if (d->thread_id == pthread_self()) { + if (reinterpret_cast<pthread_t>(d->data->threadId) == pthread_self()) { qWarning("QThread::wait: Thread tried to wait on itself"); return false; } @@ -704,7 +705,7 @@ void QThreadPrivate::setPriority(QThread::Priority threadPriority) int sched_policy; sched_param param; - if (pthread_getschedparam(thread_id, &sched_policy, ¶m) != 0) { + if (pthread_getschedparam(reinterpret_cast<pthread_t>(data->threadId), &sched_policy, ¶m) != 0) { // failed to get the scheduling policy, don't bother setting // the priority qWarning("QThread::setPriority: Cannot get scheduler parameters"); @@ -720,15 +721,15 @@ void QThreadPrivate::setPriority(QThread::Priority threadPriority) } param.sched_priority = prio; - int status = pthread_setschedparam(thread_id, sched_policy, ¶m); + int status = pthread_setschedparam(reinterpret_cast<pthread_t>(data->threadId), sched_policy, ¶m); # ifdef SCHED_IDLE // were we trying to set to idle priority and failed? if (status == -1 && sched_policy == SCHED_IDLE && errno == EINVAL) { // reset to lowest priority possible - pthread_getschedparam(thread_id, &sched_policy, ¶m); + pthread_getschedparam(reinterpret_cast<pthread_t>(data->threadId), &sched_policy, ¶m); param.sched_priority = sched_get_priority_min(sched_policy); - pthread_setschedparam(thread_id, sched_policy, ¶m); + pthread_setschedparam(reinterpret_cast<pthread_t>(data->threadId), sched_policy, ¶m); } # else Q_UNUSED(status); diff --git a/src/dbus/qdbus_symbols.cpp b/src/dbus/qdbus_symbols.cpp index b16be6637e..f91a8d2176 100644 --- a/src/dbus/qdbus_symbols.cpp +++ b/src/dbus/qdbus_symbols.cpp @@ -43,7 +43,6 @@ #include <QtCore/qlibrary.h> #endif #include <QtCore/qmutex.h> -#include <private/qmutexpool_p.h> #ifndef QT_NO_DBUS @@ -81,8 +80,10 @@ bool qdbus_loadLibDBus() static bool triedToLoadLibrary = false; #ifndef QT_NO_THREAD - QMutexLocker locker(QMutexPool::globalInstanceGet((void *)&qdbus_resolve_me)); + static QBasicMutex mutex; + QMutexLocker locker(&mutex); #endif + QLibrary *&lib = qdbus_libdbus; if (triedToLoadLibrary) return lib && lib->isLoaded(); diff --git a/src/dbus/qdbusconnection.cpp b/src/dbus/qdbusconnection.cpp index cddb7dfb95..bd25d8a6bf 100644 --- a/src/dbus/qdbusconnection.cpp +++ b/src/dbus/qdbusconnection.cpp @@ -69,6 +69,10 @@ QT_BEGIN_NAMESPACE +#ifdef Q_OS_WIN +static void preventDllUnload(); +#endif + Q_GLOBAL_STATIC(QDBusConnectionManager, _q_manager) // can be replaced with a lambda in Qt 5.7 @@ -157,6 +161,10 @@ QDBusConnectionManager::QDBusConnectionManager() this, &QDBusConnectionManager::createServer, Qt::BlockingQueuedConnection); moveToThread(this); // ugly, don't do this in other projects +#ifdef Q_OS_WIN + // prevent the library from being unloaded on Windows. See comments in the function. + preventDllUnload(); +#endif defaultBuses[0] = defaultBuses[1] = Q_NULLPTR; start(); } @@ -1282,4 +1290,31 @@ QT_END_NAMESPACE #include "qdbusconnection.moc" +#ifdef Q_OS_WIN +# include <qt_windows.h> + +QT_BEGIN_NAMESPACE +static void preventDllUnload() +{ + // Thread termination is really wacky on Windows. For some reason we don't + // understand, exiting from the thread may try to unload the DLL. Since the + // QDBusConnectionManager thread runs until the DLL is unloaded, we've got + // a deadlock: the main thread is waiting for the manager thread to exit, + // but the manager thread is attempting to acquire a lock to unload the DLL. + // + // We work around the issue by preventing the unload from happening in the + // first place. + // + // For this trick, see + // https://blogs.msdn.microsoft.com/oldnewthing/20131105-00/?p=2733 + + static HMODULE self; + GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | + GET_MODULE_HANDLE_EX_FLAG_PIN, + reinterpret_cast<const wchar_t *>(&self), // any address in this DLL + &self); +} +QT_END_NAMESPACE +#endif + #endif // QT_NO_DBUS diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 107ea73a56..81310ae2a2 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -2146,6 +2146,17 @@ bool QWindow::event(QEvent *ev) break; } + case QEvent::PlatformSurface: { + if ((static_cast<QPlatformSurfaceEvent *>(ev))->surfaceEventType() == QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed) { +#ifndef QT_NO_OPENGL + QOpenGLContext *context = QOpenGLContext::currentContext(); + if (context && context->surface() == static_cast<QSurface *>(this)) + context->doneCurrent(); +#endif + } + break; + } + default: return QObject::event(ev); } diff --git a/src/gui/opengl/qopenglcustomshaderstage.cpp b/src/gui/opengl/qopenglcustomshaderstage.cpp index a0386bd5f3..baa44f86b0 100644 --- a/src/gui/opengl/qopenglcustomshaderstage.cpp +++ b/src/gui/opengl/qopenglcustomshaderstage.cpp @@ -69,6 +69,7 @@ QOpenGLCustomShaderStage::~QOpenGLCustomShaderStage() d->m_manager->removeCustomStage(); d->m_manager->sharedShaders->cleanupCustomStage(this); } + delete d_ptr; } void QOpenGLCustomShaderStage::setUniformsDirty() diff --git a/src/gui/opengl/qopenglcustomshaderstage_p.h b/src/gui/opengl/qopenglcustomshaderstage_p.h index 099e6aadf8..2342991e5e 100644 --- a/src/gui/opengl/qopenglcustomshaderstage_p.h +++ b/src/gui/opengl/qopenglcustomshaderstage_p.h @@ -52,6 +52,7 @@ // #include <QOpenGLShaderProgram> +#include <QtGlobal> QT_BEGIN_NAMESPACE @@ -78,6 +79,8 @@ protected: private: QOpenGLCustomShaderStagePrivate* d_ptr; + + Q_DISABLE_COPY(QOpenGLCustomShaderStage) }; diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 0b205b8b0e..1b947154ef 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -6255,9 +6255,6 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const painter->setRenderHint(QPainter::Qt4CompatiblePainting, false); const qreal underlineOffset = fe->underlinePosition().toReal(); - // deliberately ceil the offset to avoid the underline coming too close to - // the text above it. - const qreal underlinePos = pos.y() + qCeil(underlineOffset) + 0.5; if (underlineStyle == QTextCharFormat::SpellCheckUnderline) { QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme(); @@ -6282,6 +6279,12 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const painter->fillRect(pos.x(), 0, qCeil(width), qMin(wave.height(), descent), wave); painter->restore(); } else if (underlineStyle != QTextCharFormat::NoUnderline) { + // Deliberately ceil the offset to avoid the underline coming too close to + // the text above it, but limit it to stay within descent. + qreal adjustedUnderlineOffset = std::ceil(underlineOffset) + 0.5; + if (underlineOffset <= fe->descent().toReal()) + adjustedUnderlineOffset = qMin(adjustedUnderlineOffset, fe->descent().toReal() - 0.5); + const qreal underlinePos = pos.y() + adjustedUnderlineOffset; QColor uc = charFormat.underlineColor(); if (uc.isValid()) pen.setColor(uc); diff --git a/src/gui/text/qtextobject.cpp b/src/gui/text/qtextobject.cpp index a756549f3e..e2130a09d9 100644 --- a/src/gui/text/qtextobject.cpp +++ b/src/gui/text/qtextobject.cpp @@ -418,9 +418,12 @@ QTextFrame::QTextFrame(QTextDocument *doc) { } -// ### DOC: What does this do to child frames? /*! - Destroys the frame, and removes it from the document's layout. + Destroys the text frame. + + \warning Text frames are owned by the document, so you should + never destroy them yourself. In order to remove a frame from + its document, remove its contents using a \c QTextCursor. */ QTextFrame::~QTextFrame() { diff --git a/src/network/kernel/qdnslookup_unix.cpp b/src/network/kernel/qdnslookup_unix.cpp index d2c5542139..35981a2f2c 100644 --- a/src/network/kernel/qdnslookup_unix.cpp +++ b/src/network/kernel/qdnslookup_unix.cpp @@ -42,7 +42,6 @@ #include <qlibrary.h> #include <qscopedpointer.h> #include <qurl.h> -#include <private/qmutexpool_p.h> #include <private/qnativesocketengine_p.h> #include <sys/types.h> @@ -78,7 +77,7 @@ struct QDnsLookupStateDeleter } }; -static void resolveLibrary() +static bool resolveLibraryInternal() { QLibrary lib; #ifdef LIBRESOLV_SO @@ -88,7 +87,7 @@ static void resolveLibrary() { lib.setFileName(QLatin1String("resolv")); if (!lib.load()) - return; + return false; } local_dn_expand = dn_expand_proto(lib.resolve("__dn_expand")); @@ -112,19 +111,15 @@ static void resolveLibrary() local_res_nquery = res_nquery_proto(lib.resolve("res_9_nquery")); if (!local_res_nquery) local_res_nquery = res_nquery_proto(lib.resolve("res_nquery")); + + return true; } +Q_GLOBAL_STATIC_WITH_ARGS(bool, resolveLibrary, (resolveLibraryInternal())) void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestName, const QHostAddress &nameserver, QDnsLookupReply *reply) { // Load dn_expand, res_ninit and res_nquery on demand. - static QBasicAtomicInt triedResolve = Q_BASIC_ATOMIC_INITIALIZER(false); - if (!triedResolve.loadAcquire()) { - QMutexLocker locker(QMutexPool::globalInstanceGet(&local_res_ninit)); - if (!triedResolve.load()) { - resolveLibrary(); - triedResolve.storeRelease(true); - } - } + resolveLibrary(); // If dn_expand, res_ninit or res_nquery is missing, fail. if (!local_dn_expand || !local_res_nclose || !local_res_ninit || !local_res_nquery) { diff --git a/src/network/kernel/qhostinfo_unix.cpp b/src/network/kernel/qhostinfo_unix.cpp index 8a3f3fa5c9..7af8db73e0 100644 --- a/src/network/kernel/qhostinfo_unix.cpp +++ b/src/network/kernel/qhostinfo_unix.cpp @@ -49,7 +49,6 @@ #include <qbasicatomic.h> #include <qurl.h> #include <qfile.h> -#include <private/qmutexpool_p.h> #include <private/qnet_unix_p.h> #include <sys/types.h> @@ -92,7 +91,7 @@ typedef void (*res_nclose_proto)(res_state_ptr); static res_nclose_proto local_res_nclose = 0; static res_state_ptr local_res = 0; -static void resolveLibrary() +static bool resolveLibraryInternal() { #if !defined(QT_NO_LIBRARY) && !defined(Q_OS_QNX) QLibrary lib; @@ -103,7 +102,7 @@ static void resolveLibrary() { lib.setFileName(QLatin1String("resolv")); if (!lib.load()) - return; + return false; } local_res_init = res_init_proto(lib.resolve("__res_init")); @@ -125,7 +124,10 @@ static void resolveLibrary() local_res_ninit = 0; } #endif + + return true; } +Q_GLOBAL_STATIC_WITH_ARGS(bool, resolveLibrary, (resolveLibraryInternal())) QHostInfo QHostInfoAgent::fromName(const QString &hostName) { @@ -137,14 +139,7 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName) #endif // Load res_init on demand. - static QBasicAtomicInt triedResolve = Q_BASIC_ATOMIC_INITIALIZER(false); - if (!triedResolve.loadAcquire()) { - QMutexLocker locker(QMutexPool::globalInstanceGet(&local_res_init)); - if (!triedResolve.load()) { - resolveLibrary(); - triedResolve.storeRelease(true); - } - } + resolveLibrary(); // If res_init is available, poll it. if (local_res_init) diff --git a/src/network/kernel/qhostinfo_win.cpp b/src/network/kernel/qhostinfo_win.cpp index cc6102a713..b98f36a612 100644 --- a/src/network/kernel/qhostinfo_win.cpp +++ b/src/network/kernel/qhostinfo_win.cpp @@ -45,7 +45,6 @@ #include <qmutex.h> #include <qbasicatomic.h> #include <qurl.h> -#include <private/qmutexpool_p.h> QT_BEGIN_NAMESPACE @@ -78,7 +77,7 @@ static getnameinfoProto local_getnameinfo = 0; static getaddrinfoProto local_getaddrinfo = 0; static freeaddrinfoProto local_freeaddrinfo = 0; -static void resolveLibrary() +static bool resolveLibraryInternal() { // Attempt to resolve getaddrinfo(); without it we'll have to fall // back to gethostbyname(), which has no IPv6 support. @@ -95,7 +94,9 @@ static void resolveLibrary() local_freeaddrinfo = (freeaddrinfoProto) QSystemLibrary::resolve(QLatin1String("ws2_32"), "freeaddrinfo"); local_getnameinfo = (getnameinfoProto) QSystemLibrary::resolve(QLatin1String("ws2_32"), "getnameinfo"); #endif + return true; } +Q_GLOBAL_STATIC_WITH_ARGS(bool, resolveLibrary, (resolveLibraryInternal())) static void translateWSAError(int error, QHostInfo *results) { @@ -123,14 +124,7 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName) QSysInfo::machineHostName(); // this initializes ws2_32.dll // Load res_init on demand. - static QBasicAtomicInt triedResolve = Q_BASIC_ATOMIC_INITIALIZER(false); - if (!triedResolve.loadAcquire()) { - QMutexLocker locker(QMutexPool::globalInstanceGet(&local_getaddrinfo)); - if (!triedResolve.load()) { - resolveLibrary(); - triedResolve.storeRelease(true); - } - } + resolveLibrary(); QHostInfo results; diff --git a/src/network/socket/qlocalsocket.h b/src/network/socket/qlocalsocket.h index da91ef0e85..0eecab206b 100644 --- a/src/network/socket/qlocalsocket.h +++ b/src/network/socket/qlocalsocket.h @@ -130,7 +130,7 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_stateChanged(QAbstractSocket::SocketState)) Q_PRIVATE_SLOT(d_func(), void _q_error(QAbstractSocket::SocketError)) #elif defined(Q_OS_WIN) - Q_PRIVATE_SLOT(d_func(), void _q_bytesWritten(qint64)) + Q_PRIVATE_SLOT(d_func(), void _q_canWrite()) Q_PRIVATE_SLOT(d_func(), void _q_pipeClosed()) Q_PRIVATE_SLOT(d_func(), void _q_winError(ulong, const QString &)) #else diff --git a/src/network/socket/qlocalsocket_p.h b/src/network/socket/qlocalsocket_p.h index 0f84aeea3e..cf36887e92 100644 --- a/src/network/socket/qlocalsocket_p.h +++ b/src/network/socket/qlocalsocket_p.h @@ -130,8 +130,7 @@ public: ~QLocalSocketPrivate(); void destroyPipeHandles(); void setErrorString(const QString &function); - void startNextWrite(); - void _q_bytesWritten(qint64 bytes); + void _q_canWrite(); void _q_pipeClosed(); void _q_winError(ulong windowsError, const QString &function); HANDLE handle; diff --git a/src/network/socket/qlocalsocket_win.cpp b/src/network/socket/qlocalsocket_win.cpp index 5fc34c3ed6..66b461522b 100644 --- a/src/network/socket/qlocalsocket_win.cpp +++ b/src/network/socket/qlocalsocket_win.cpp @@ -218,11 +218,12 @@ qint64 QLocalSocket::writeData(const char *data, qint64 len) memcpy(dest, data, len); if (!d->pipeWriter) { d->pipeWriter = new QWindowsPipeWriter(d->handle, this); - QObjectPrivate::connect(d->pipeWriter, &QWindowsPipeWriter::bytesWritten, - d, &QLocalSocketPrivate::_q_bytesWritten); + connect(d->pipeWriter, &QWindowsPipeWriter::bytesWritten, + this, &QLocalSocket::bytesWritten); + QObjectPrivate::connect(d->pipeWriter, &QWindowsPipeWriter::canWrite, + d, &QLocalSocketPrivate::_q_canWrite); } - if (!d->pipeWriter->isWriteOperationActive()) - d->startNextWrite(); + d->_q_canWrite(); return len; } @@ -275,7 +276,7 @@ qint64 QLocalSocket::bytesAvailable() const qint64 QLocalSocket::bytesToWrite() const { Q_D(const QLocalSocket); - return d->writeBuffer.size(); + return d->writeBuffer.size() + (d->pipeWriter ? d->pipeWriter->bytesToWrite() : 0); } bool QLocalSocket::canReadLine() const @@ -358,7 +359,7 @@ bool QLocalSocket::setSocketDescriptor(qintptr socketDescriptor, return true; } -void QLocalSocketPrivate::startNextWrite() +void QLocalSocketPrivate::_q_canWrite() { Q_Q(QLocalSocket); if (writeBuffer.isEmpty()) { @@ -366,18 +367,11 @@ void QLocalSocketPrivate::startNextWrite() q->close(); } else { Q_ASSERT(pipeWriter); - pipeWriter->write(writeBuffer.readPointer(), writeBuffer.nextDataBlockSize()); + if (!pipeWriter->isWriteOperationActive()) + pipeWriter->write(writeBuffer.read()); } } -void QLocalSocketPrivate::_q_bytesWritten(qint64 bytes) -{ - Q_Q(QLocalSocket); - writeBuffer.free(bytes); - startNextWrite(); - emit q->bytesWritten(bytes); -} - qintptr QLocalSocket::socketDescriptor() const { Q_D(const QLocalSocket); diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp index 6ff5c884f7..5ffe7b11b8 100644 --- a/src/network/socket/qnativesocketengine_win.cpp +++ b/src/network/socket/qnativesocketengine_win.cpp @@ -574,6 +574,19 @@ bool QNativeSocketEnginePrivate::fetchConnectionParameters() } } + // Some Windows kernels return a v4-mapped QHostAddress::AnyIPv4 as a + // 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) { + bool ok = false; + const quint32 localIPv4 = localAddress.toIPv4Address(&ok); + if (ok && localIPv4 == INADDR_ANY) { + socketProtocol = QAbstractSocket::AnyIPProtocol; + localAddress = QHostAddress::Any; + } + } + memset(&sa, 0, sizeof(sa)); if (::getpeername(socketDescriptor, &sa.a, &sockAddrSize) == 0) { qt_socket_getPortAndAddress(socketDescriptor, &sa, &peerPort, &peerAddress); @@ -1186,7 +1199,7 @@ qint64 QNativeSocketEnginePrivate::nativePendingDatagramSize() const #endif #if defined (QNATIVESOCKETENGINE_DEBUG) - qDebug("QNativeSocketEnginePrivate::nativePendingDatagramSize() == %li", ret); + qDebug("QNativeSocketEnginePrivate::nativePendingDatagramSize() == %lli", ret); #endif return ret; @@ -1292,10 +1305,11 @@ qint64 QNativeSocketEnginePrivate::nativeReceiveDatagram(char *data, qint64 maxL } #if defined (QNATIVESOCKETENGINE_DEBUG) - qDebug("QNativeSocketEnginePrivate::nativeReceiveDatagram(%p \"%s\", %li, %s, %i) == %li", + bool printSender = (ret != -1 && (options & QNativeSocketEngine::WantDatagramSender) != 0); + qDebug("QNativeSocketEnginePrivate::nativeReceiveDatagram(%p \"%s\", %lli, %s, %i) == %lli", data, qt_prettyDebug(data, qMin<qint64>(ret, 16), ret).data(), maxLength, - address ? address->toString().toLatin1().constData() : "(nil)", - port ? *port : 0, ret); + printSender ? header->senderAddress.toString().toLatin1().constData() : "(unknown)", + printSender ? header->senderPort : 0, ret); #endif return ret; @@ -1407,9 +1421,10 @@ qint64 QNativeSocketEnginePrivate::nativeSendDatagram(const char *data, qint64 l } #if defined (QNATIVESOCKETENGINE_DEBUG) - qDebug("QNativeSocketEnginePrivate::nativeSendDatagram(%p \"%s\", %li, \"%s\", %i) == %li", data, - qt_prettyDebug(data, qMin<qint64>(len, 16), len).data(), 0, address.toString().toLatin1().constData(), - port, ret); + qDebug("QNativeSocketEnginePrivate::nativeSendDatagram(%p \"%s\", %lli, \"%s\", %i) == %lli", data, + qt_prettyDebug(data, qMin<qint64>(len, 16), len).data(), len, + header.destinationAddress.toString().toLatin1().constData(), + header.destinationPort, ret); #endif return ret; diff --git a/src/plugins/bearer/android/jar/jar.pri b/src/plugins/bearer/android/jar/jar.pri index 6d9aac3bb3..e43dbf0711 100644 --- a/src/plugins/bearer/android/jar/jar.pri +++ b/src/plugins/bearer/android/jar/jar.pri @@ -9,5 +9,3 @@ JAVASOURCES += $$PWD/src/org/qtproject/qt5/android/bearer/QtNetworkReceiver.java # install target.path = $$[QT_INSTALL_PREFIX]/jar INSTALLS += target - -OTHER_FILES += $$JAVASOURCES diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 697cece77f..3115db2b83 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -75,6 +75,8 @@ static QTouchDevice *touchDevice = 0; // ### HACK Remove once 10.8 is unsupported static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil; +static bool _q_dontOverrideCtrlLMB = false; + @interface NSEvent (Qt_Compile_Leopard_DeviceDelta) - (CGFloat)deviceDeltaX; - (CGFloat)deviceDeltaY; @@ -135,6 +137,8 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil; NSString **notificationNameVar = (NSString **)dlsym(RTLD_NEXT, "NSWindowDidChangeOcclusionStateNotification"); if (notificationNameVar) _q_NSWindowDidChangeOcclusionStateNotification = *notificationNameVar; + + _q_dontOverrideCtrlLMB = qt_mac_resolveOption(false, "QT_MAC_DONT_OVERRIDE_CTRL_LMB"); } - (id) init @@ -969,7 +973,7 @@ QT_WARNING_POP if ([self hasMarkedText]) { [[NSTextInputContext currentInputContext] handleEvent:theEvent]; } else { - if ([QNSView convertKeyModifiers:[theEvent modifierFlags]] & Qt::MetaModifier) { + if (!_q_dontOverrideCtrlLMB && [QNSView convertKeyModifiers:[theEvent modifierFlags]] & Qt::MetaModifier) { m_buttons |= Qt::RightButton; m_sendUpAsRightButton = true; } else { diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.cpp index 8536e2c239..d96c3964df 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.cpp @@ -107,8 +107,10 @@ QEglFSKmsGbmCursor::~QEglFSKmsGbmCursor() drmModeMoveCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, 0, 0); } - gbm_bo_destroy(m_bo); - m_bo = Q_NULLPTR; + if (m_bo) { + gbm_bo_destroy(m_bo); + m_bo = Q_NULLPTR; + } } void QEglFSKmsGbmCursor::pointerEvent(const QMouseEvent &event) @@ -121,6 +123,9 @@ void QEglFSKmsGbmCursor::changeCursor(QCursor *windowCursor, QWindow *window) { Q_UNUSED(window); + if (!m_bo) + return; + if (!m_visible) return; diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h index 461298269d..56a0874bb4 100644 --- a/src/plugins/platforms/ios/qiosscreen.h +++ b/src/plugins/platforms/ios/qiosscreen.h @@ -79,7 +79,7 @@ private: QRect m_geometry; QRect m_availableGeometry; int m_depth; - uint m_pixelDensity; + uint m_physicalDpi; QSizeF m_physicalSize; QIOSOrientationListener *m_orientationListener; }; diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index 29cb5876af..bfd22abaa4 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -186,18 +186,18 @@ QIOSScreen::QIOSScreen(UIScreen *screen) if (deviceIdentifier.contains(QRegularExpression("^iPhone(7,1|8,2)$"))) { // iPhone 6 Plus or iPhone 6S Plus - m_pixelDensity = 401; + m_physicalDpi = 401; } else if (deviceIdentifier.contains(QRegularExpression("^iPad(1,1|2,[1-4]|3,[1-6]|4,[1-3]|5,[3-4]|6,[7-8])$"))) { // All iPads except the iPad Mini series - m_pixelDensity = 132 * devicePixelRatio(); + m_physicalDpi = 132 * devicePixelRatio(); } else { // All non-Plus iPhones, and iPad Minis - m_pixelDensity = 163 * devicePixelRatio(); + m_physicalDpi = 163 * devicePixelRatio(); } } else { // External display, hard to say m_depth = 24; - m_pixelDensity = 96; + m_physicalDpi = 96; } for (UIWindow *existingWindow in [[UIApplication sharedApplication] windows]) { @@ -259,8 +259,23 @@ void QIOSScreen::updateProperties() } if (m_geometry != previousGeometry) { - const qreal millimetersPerInch = 25.4; - m_physicalSize = QSizeF(m_geometry.size() * devicePixelRatio()) / m_pixelDensity * millimetersPerInch; + QRectF physicalGeometry; + if (QSysInfo::MacintoshVersion >= QSysInfo::MV_IOS_8_0) { + // We can't use the primaryOrientation of screen(), as we haven't reported the new geometry yet + Qt::ScreenOrientation primaryOrientation = m_geometry.width() >= m_geometry.height() ? + Qt::LandscapeOrientation : Qt::PortraitOrientation; + + // On iPhone 6+ devices, or when display zoom is enabled, the render buffer is scaled + // before being output on the physical display. We have to take this into account when + // computing the physical size. Note that unlike the native bounds, the physical size + // follows the primary orientation of the screen. + physicalGeometry = mapBetween(nativeOrientation(), primaryOrientation, fromCGRect(m_uiScreen.nativeBounds).toRect()); + } else { + physicalGeometry = QRectF(0, 0, m_geometry.width() * devicePixelRatio(), m_geometry.height() * devicePixelRatio()); + } + + static const qreal millimetersPerInch = 25.4; + m_physicalSize = physicalGeometry.size() / m_physicalDpi * millimetersPerInch; } // At construction time, we don't yet have an associated QScreen, but we still want diff --git a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp index d123bdf82d..321e124eee 100644 --- a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp +++ b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp @@ -263,15 +263,15 @@ static int openTtyDevice(const QString &device) return fd; } -static bool switchToGraphicsMode(int ttyfd, int *oldMode) +static void switchToGraphicsMode(int ttyfd, bool doSwitch, int *oldMode) { - ioctl(ttyfd, KDGETMODE, oldMode); - if (*oldMode != KD_GRAPHICS) { - if (ioctl(ttyfd, KDSETMODE, KD_GRAPHICS) != 0) - return false; + // Do not warn if the switch fails: the ioctl fails when launching from a + // remote console and there is nothing we can do about it. The matching + // call in resetTty should at least fail then, too, so we do no harm. + if (ioctl(ttyfd, KDGETMODE, oldMode) == 0) { + if (doSwitch && *oldMode != KD_GRAPHICS) + ioctl(ttyfd, KDSETMODE, KD_GRAPHICS); } - - return true; } static void resetTty(int ttyfd, int oldMode) @@ -287,14 +287,16 @@ static void blankScreen(int fd, bool on) } QLinuxFbScreen::QLinuxFbScreen(const QStringList &args) - : mArgs(args), mFbFd(-1), mBlitter(0) + : mArgs(args), mFbFd(-1), mTtyFd(-1), mBlitter(0) { + mMmap.data = 0; } QLinuxFbScreen::~QLinuxFbScreen() { if (mFbFd != -1) { - munmap(mMmap.data - mMmap.offset, mMmap.size); + if (mMmap.data) + munmap(mMmap.data - mMmap.offset, mMmap.size); close(mFbFd); } @@ -394,11 +396,7 @@ bool QLinuxFbScreen::initialize() if (mTtyFd == -1) qErrnoWarning(errno, "Failed to open tty"); - if (doSwitchToGraphicsMode) - switchToGraphicsMode(mTtyFd, &mOldTtyMode); - // Do not warn if the switch fails: the ioctl fails when launching from - // a remote console and there is nothing we can do about it. - + switchToGraphicsMode(mTtyFd, doSwitchToGraphicsMode, &mOldTtyMode); blankScreen(mFbFd, false); return true; diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 2126c271f9..87b4c7b91f 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -1638,8 +1638,13 @@ bool QXcbConnection::compressEvent(xcb_generic_event_t *event, int currentIndex, if (!m_xi2Enabled) return false; - // compress XI_Motion + // compress XI_Motion, but not from tablet devices if (isXIType(event, m_xiOpCode, XI_Motion)) { +#ifndef QT_NO_TABLETEVENT + xXIDeviceEvent *xdev = reinterpret_cast<xXIDeviceEvent *>(event); + if (const_cast<QXcbConnection *>(this)->tabletDataForDevice(xdev->sourceid)) + return false; +#endif // QT_NO_TABLETEVENT for (int j = nextIndex; j < eventqueue->size(); ++j) { xcb_generic_event_t *next = eventqueue->at(j); if (!isValid(next)) diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index 68d7b5622f..891f0fbcb5 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -584,6 +584,7 @@ private: bool xi2HandleTabletEvent(const void *event, TabletData *tabletData); void xi2ReportTabletEvent(const void *event, TabletData *tabletData); QVector<TabletData> m_tabletData; + TabletData *tabletDataForDevice(int id); #endif // !QT_NO_TABLETEVENT struct ScrollingDevice { ScrollingDevice() : deviceId(0), verticalIndex(0), horizontalIndex(0), orientations(0), legacyOrientations(0) { } diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index 836761c9b9..5b7f45fb6c 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -119,7 +119,7 @@ void QXcbConnection::xi2SetupDevices() // Only non-master pointing devices are relevant here. if (devices[i].use != XISlavePointer) continue; - qCDebug(lcQpaXInputDevices) << "input device "<< devices[i].name; + qCDebug(lcQpaXInputDevices) << "input device " << devices[i].name << "ID" << devices[i].deviceid; #ifndef QT_NO_TABLETEVENT TabletData tabletData; #endif @@ -537,12 +537,9 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event) #ifndef QT_NO_TABLETEVENT if (!xiEnterEvent) { - for (int i = 0; i < m_tabletData.count(); ++i) { - if (m_tabletData.at(i).deviceId == sourceDeviceId) { - if (xi2HandleTabletEvent(xiEvent, &m_tabletData[i])) - return; - } - } + QXcbConnection::TabletData *tablet = tabletDataForDevice(sourceDeviceId); + if (tablet && xi2HandleTabletEvent(xiEvent, tablet)) + return; } #endif // QT_NO_TABLETEVENT @@ -1195,6 +1192,16 @@ void QXcbConnection::xi2ReportTabletEvent(const void *event, TabletData *tabletD xTilt, yTilt, tangentialPressure, rotation, 0, tabletData->serialId); } + +QXcbConnection::TabletData *QXcbConnection::tabletDataForDevice(int id) +{ + for (int i = 0; i < m_tabletData.count(); ++i) { + if (m_tabletData.at(i).deviceId == id) + return &m_tabletData[i]; + } + return Q_NULLPTR; +} + #endif // QT_NO_TABLETEVENT #endif // XCB_USE_XINPUT2 diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp index 1c9faa17ea..b55fbd8f03 100644 --- a/src/plugins/platforms/xcb/qxcbdrag.cpp +++ b/src/plugins/platforms/xcb/qxcbdrag.cpp @@ -1140,10 +1140,10 @@ void QXcbDrag::handleSelectionRequest(const xcb_selection_request_event_t *event at = findTransactionByWindow(event->requestor); } - if (at == -1 && event->time == XCB_CURRENT_TIME) { + if (at == -1) { xcb_window_t target = findXdndAwareParent(connection(), event->requestor); if (target) { - if (current_target == target) + if (event->time == XCB_CURRENT_TIME && current_target == target) at = -2; else at = findTransactionByWindow(target); diff --git a/src/widgets/widgets/qsplitter.cpp b/src/widgets/widgets/qsplitter.cpp index e3ca6b0a79..17b7a9ebb3 100644 --- a/src/widgets/widgets/qsplitter.cpp +++ b/src/widgets/widgets/qsplitter.cpp @@ -1099,6 +1099,8 @@ void QSplitter::resizeEvent(QResizeEvent *) If \a widget is already in the splitter, it will be moved to the new position. + \note The splitter takes ownership of the widget. + \sa insertWidget(), widget(), indexOf() */ void QSplitter::addWidget(QWidget *widget) @@ -1113,7 +1115,9 @@ void QSplitter::addWidget(QWidget *widget) If \a widget is already in the splitter, it will be moved to the new position. - if \a index is an invalid index, then the widget will be inserted at the end. + If \a index is an invalid index, then the widget will be inserted at the end. + + \note The splitter takes ownership of the widget. \sa addWidget(), indexOf(), widget() */ diff --git a/tests/auto/corelib/io/qloggingregistry/qloggingregistry.pro b/tests/auto/corelib/io/qloggingregistry/qloggingregistry.pro index 321420c2df..287ab30993 100644 --- a/tests/auto/corelib/io/qloggingregistry/qloggingregistry.pro +++ b/tests/auto/corelib/io/qloggingregistry/qloggingregistry.pro @@ -5,7 +5,6 @@ CONFIG += testcase QT = core core-private testlib SOURCES += tst_qloggingregistry.cpp -OTHER_FILES += qtlogging.ini TESTDATA += qtlogging.ini android { diff --git a/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp b/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp index 83838570be..cf43e391b5 100644 --- a/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp +++ b/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp @@ -644,22 +644,21 @@ void tst_QTimeLine::restart() void tst_QTimeLine::setPaused() { - QTimeLine timeLine(1000); + const int EndTime = 10000; + QTimeLine timeLine(EndTime); { QCOMPARE(timeLine.currentTime(), 0); timeLine.start(); - QTest::qWait(250); + QTRY_VERIFY(timeLine.currentTime() != 0); // wait for start timeLine.setPaused(true); int oldCurrentTime = timeLine.currentTime(); QVERIFY(oldCurrentTime > 0); - QVERIFY(oldCurrentTime < 1000); + QVERIFY(oldCurrentTime < EndTime); QTest::qWait(1000); timeLine.setPaused(false); - QTest::qWait(250); - int currentTime = timeLine.currentTime(); - QVERIFY(currentTime > 0); - QVERIFY(currentTime > oldCurrentTime); - QVERIFY(currentTime < 1000); + QTRY_VERIFY(timeLine.currentTime() > oldCurrentTime); + QVERIFY(timeLine.currentTime() > 0); + QVERIFY(timeLine.currentTime() < EndTime); timeLine.stop(); } } diff --git a/tests/auto/gui/kernel/qkeyevent/tst_qkeyevent.cpp b/tests/auto/gui/kernel/qkeyevent/tst_qkeyevent.cpp index db0bfaf622..811a6d111f 100644 --- a/tests/auto/gui/kernel/qkeyevent/tst_qkeyevent.cpp +++ b/tests/auto/gui/kernel/qkeyevent/tst_qkeyevent.cpp @@ -116,6 +116,23 @@ static bool orderByModifier(const QVector<int> &v1, const QVector<int> &v2) return true; } +static QByteArray modifiersTestRowName(const QString &keySequence) +{ + QByteArray result; + QTextStream str(&result); + for (int i = 0, size = keySequence.size(); i < size; ++i) { + const QChar &c = keySequence.at(i); + const ushort uc = c.unicode(); + if (uc > 32 && uc < 128) + str << '"' << c << '"'; + else + str << "U+" << hex << uc << dec; + if (i < size - 1) + str << ','; + } + return result; +} + void tst_QKeyEvent::modifiers_data() { struct Modifier @@ -155,7 +172,8 @@ void tst_QKeyEvent::modifiers_data() mods |= modifier.modifier; } QKeySequence keySequence(keys[0], keys[1], keys[2], keys[3]); - QTest::newRow(keySequence.toString(QKeySequence::NativeText).toUtf8().constData()) << mods; + QTest::newRow(modifiersTestRowName(keySequence.toString(QKeySequence::NativeText)).constData()) + << mods; } } diff --git a/tests/auto/network-settings.h b/tests/auto/network-settings.h index d6b63c6100..16966ced4e 100644 --- a/tests/auto/network-settings.h +++ b/tests/auto/network-settings.h @@ -29,6 +29,8 @@ #include <QString> #ifdef QT_NETWORK_LIB #include <QtNetwork/QHostInfo> +#include <QtNetwork/QHostAddress> +#include <QtNetwork/QAbstractSocket> #endif #ifdef Q_OS_UNIX @@ -134,5 +136,21 @@ public: } return true; } -#endif + + // Helper function for usage with QVERIFY2 on sockets. + static QByteArray msgSocketError(const QAbstractSocket &s) + { + QString result; + QDebug debug(&result); + debug.nospace(); + debug.noquote(); + if (!s.localAddress().isNull()) + debug << "local=" << s.localAddress().toString() << ':' << s.localPort(); + if (!s.peerAddress().isNull()) + debug << ", peer=" << s.peerAddress().toString() << ':' << s.peerPort(); + debug << ", type=" << s.socketType() << ", state=" << s.state() + << ", error=" << s.error() << ": " << s.errorString(); + return result.toLocal8Bit(); + } +#endif // QT_NETWORK_LIB }; diff --git a/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp b/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp index d0baa62e29..4bea9b116c 100644 --- a/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp +++ b/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp @@ -31,6 +31,7 @@ #include <QtTest/QtTest> #include <qtextstream.h> +#include <qdatastream.h> #include <QtNetwork/qlocalsocket.h> #include <QtNetwork/qlocalserver.h> @@ -73,6 +74,9 @@ private slots: void readBufferOverflow(); + void simpleCommandProtocol1(); + void simpleCommandProtocol2(); + void fullPath(); void hitMaximumConnections_data(); @@ -622,6 +626,110 @@ void tst_QLocalSocket::readBufferOverflow() QCOMPARE(client.bytesAvailable(), 0); } +static qint64 writeCommand(const QVariant &command, QIODevice *device, int commandCounter) +{ + QByteArray block; + QDataStream out(&block, QIODevice::WriteOnly); + out << qint64(0); + out << commandCounter; + out << command; + out.device()->seek(0); + out << qint64(block.size() - sizeof(qint64)); + return device->write(block); +} + +static QVariant readCommand(QIODevice *ioDevice, int *readCommandCounter, bool readSize = true) +{ + QDataStream in(ioDevice); + qint64 blockSize; + int commandCounter; + if (readSize) + in >> blockSize; + in >> commandCounter; + *readCommandCounter = commandCounter; + + QVariant command; + in >> command; + + return command; +} + +void tst_QLocalSocket::simpleCommandProtocol1() +{ + QLocalServer server; + server.listen(QStringLiteral("simpleProtocol")); + + QLocalSocket localSocketWrite; + localSocketWrite.connectToServer(server.serverName()); + QVERIFY(server.waitForNewConnection()); + QLocalSocket *localSocketRead = server.nextPendingConnection(); + QVERIFY(localSocketRead); + + int readCounter = 0; + for (int i = 0; i < 2000; ++i) { + const QVariant command(QRect(readCounter, i, 10, 10)); + const qint64 blockSize = writeCommand(command, &localSocketWrite, i); + while (localSocketWrite.bytesToWrite()) + QVERIFY(localSocketWrite.waitForBytesWritten()); + while (localSocketRead->bytesAvailable() < blockSize) { + QVERIFY(localSocketRead->waitForReadyRead(1000)); + } + const QVariant variant = readCommand(localSocketRead, &readCounter); + QCOMPARE(readCounter, i); + QCOMPARE(variant, command); + } +} + +void tst_QLocalSocket::simpleCommandProtocol2() +{ + QLocalServer server; + server.listen(QStringLiteral("simpleProtocol")); + + QLocalSocket localSocketWrite; + localSocketWrite.connectToServer(server.serverName()); + QVERIFY(server.waitForNewConnection()); + QLocalSocket* localSocketRead = server.nextPendingConnection(); + QVERIFY(localSocketRead); + + int readCounter = 0; + qint64 writtenBlockSize = 0; + qint64 blockSize = 0; + + QObject::connect(localSocketRead, &QLocalSocket::readyRead, [&] { + forever { + if (localSocketRead->bytesAvailable() < sizeof(qint64)) + return; + + if (blockSize == 0) { + QDataStream in(localSocketRead); + in >> blockSize; + } + + if (localSocketRead->bytesAvailable() < blockSize) + return; + + int commandNumber = 0; + const QVariant variant = readCommand(localSocketRead, &commandNumber, false); + QCOMPARE(writtenBlockSize, blockSize); + QCOMPARE(readCounter, commandNumber); + QCOMPARE(variant.userType(), (int)QMetaType::QRect); + + readCounter++; + blockSize = 0; + } + }); + + for (int i = 0; i < 500; ++i) { + const QVariant command(QRect(readCounter, i, 10, 10)); + writtenBlockSize = writeCommand(command, &localSocketWrite, i) - sizeof(qint64); + if (i % 10 == 0) + QTest::qWait(1); + } + + localSocketWrite.abort(); + QVERIFY(localSocketRead->waitForDisconnected(1000)); +} + // QLocalSocket/Server can take a name or path, check that it works as expected void tst_QLocalSocket::fullPath() { diff --git a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp index 7565097942..382fbf08a8 100644 --- a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp +++ b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp @@ -671,8 +671,10 @@ void tst_QTcpSocket::bindThenResolveHost() dummySocket.close(); - socket->connectToHost(hostName, 80); - QVERIFY2(socket->waitForConnected(), "Network timeout"); + const quint16 port = 80; + socket->connectToHost(hostName, port); + QVERIFY2(socket->waitForConnected(), (hostName.toLocal8Bit() + ": " + QByteArray::number(port) + ' ' + + QtNetworkSettings::msgSocketError(*socket)).constData()); QCOMPARE(socket->localPort(), boundPort); QCOMPARE(socket->socketDescriptor(), fd); diff --git a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp index 8a0784f4e5..ba49e8b041 100644 --- a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp +++ b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp @@ -33,6 +33,7 @@ #include <qcoreapplication.h> #include <qfileinfo.h> #include <qdatastream.h> +#include <qdebug.h> #include <qudpsocket.h> #include <qhostaddress.h> #include <qhostinfo.h> @@ -246,7 +247,7 @@ void tst_QUdpSocket::unconnectedServerAndClientTest() char buf[1024]; QHostAddress host; quint16 port; - QVERIFY(serverSocket.waitForReadyRead(5000)); + QVERIFY2(serverSocket.waitForReadyRead(5000), QtNetworkSettings::msgSocketError(serverSocket).constData()); QCOMPARE(int(serverSocket.readDatagram(buf, sizeof(buf), &host, &port)), int(strlen(message[i]))); buf[strlen(message[i])] = '\0'; @@ -378,8 +379,8 @@ void tst_QUdpSocket::loop() QCOMPARE(paul.writeDatagram(paulMessage.data(), paulMessage.length(), peterAddress, peter.localPort()), qint64(paulMessage.length())); - QVERIFY(peter.waitForReadyRead(9000)); - QVERIFY(paul.waitForReadyRead(9000)); + QVERIFY2(peter.waitForReadyRead(9000), QtNetworkSettings::msgSocketError(peter).constData()); + QVERIFY2(paul.waitForReadyRead(9000), QtNetworkSettings::msgSocketError(paul).constData()); char peterBuffer[16*1024]; char paulBuffer[16*1024]; if (success) { @@ -435,8 +436,8 @@ void tst_QUdpSocket::ipv6Loop() char peterBuffer[16*1024]; char paulBuffer[16*1024]; #if !defined(Q_OS_WINCE) - QVERIFY(peter.waitForReadyRead(5000)); - QVERIFY(paul.waitForReadyRead(5000)); + QVERIFY2(peter.waitForReadyRead(5000), QtNetworkSettings::msgSocketError(peter).constData()); + QVERIFY2(paul.waitForReadyRead(5000), QtNetworkSettings::msgSocketError(paul).constData()); #else QVERIFY(peter.waitForReadyRead(15000)); QVERIFY(paul.waitForReadyRead(15000)); @@ -471,7 +472,7 @@ void tst_QUdpSocket::dualStack() QByteArray buffer; //test v4 -> dual QCOMPARE((int)v4Sock.writeDatagram(v4Data.constData(), v4Data.length(), QHostAddress(QHostAddress::LocalHost), dualSock.localPort()), v4Data.length()); - QVERIFY(dualSock.waitForReadyRead(5000)); + QVERIFY2(dualSock.waitForReadyRead(5000), QtNetworkSettings::msgSocketError(dualSock).constData()); buffer.reserve(100); qint64 size = dualSock.readDatagram(buffer.data(), 100, &from, &port); QCOMPARE((int)size, v4Data.length()); @@ -485,7 +486,7 @@ void tst_QUdpSocket::dualStack() //test v6 -> dual QCOMPARE((int)v6Sock.writeDatagram(v6Data.constData(), v6Data.length(), QHostAddress(QHostAddress::LocalHostIPv6), dualSock.localPort()), v6Data.length()); - QVERIFY(dualSock.waitForReadyRead(5000)); + QVERIFY2(dualSock.waitForReadyRead(5000), QtNetworkSettings::msgSocketError(dualSock).constData()); buffer.reserve(100); size = dualSock.readDatagram(buffer.data(), 100, &from, &port); QCOMPARE((int)size, v6Data.length()); @@ -494,7 +495,7 @@ void tst_QUdpSocket::dualStack() //test dual -> v6 QCOMPARE((int)dualSock.writeDatagram(dualData.constData(), dualData.length(), QHostAddress(QHostAddress::LocalHostIPv6), v6Sock.localPort()), dualData.length()); - QVERIFY(v6Sock.waitForReadyRead(5000)); + QVERIFY2(v6Sock.waitForReadyRead(5000), QtNetworkSettings::msgSocketError(v6Sock).constData()); buffer.reserve(100); size = v6Sock.readDatagram(buffer.data(), 100, &from, &port); QCOMPARE((int)size, dualData.length()); @@ -504,7 +505,7 @@ void tst_QUdpSocket::dualStack() //test dual -> v4 QCOMPARE((int)dualSock.writeDatagram(dualData.constData(), dualData.length(), QHostAddress(QHostAddress::LocalHost), v4Sock.localPort()), dualData.length()); - QVERIFY(v4Sock.waitForReadyRead(5000)); + QVERIFY2(v4Sock.waitForReadyRead(5000), QtNetworkSettings::msgSocketError(v4Sock).constData()); buffer.reserve(100); size = v4Sock.readDatagram(buffer.data(), 100, &from, &port); QCOMPARE((int)size, dualData.length()); @@ -536,7 +537,7 @@ void tst_QUdpSocket::dualStackAutoBinding() QUdpSocket dualSock; QCOMPARE((int)dualSock.writeDatagram(dualData.constData(), dualData.length(), QHostAddress(QHostAddress::LocalHost), v4Sock.localPort()), dualData.length()); - QVERIFY(v4Sock.waitForReadyRead(5000)); + QVERIFY2(v4Sock.waitForReadyRead(5000), QtNetworkSettings::msgSocketError(v4Sock).constData()); buffer.reserve(100); size = v4Sock.readDatagram(buffer.data(), 100, &from, &port); QCOMPARE((int)size, dualData.length()); @@ -544,7 +545,7 @@ void tst_QUdpSocket::dualStackAutoBinding() QCOMPARE(buffer, dualData); QCOMPARE((int)dualSock.writeDatagram(dualData.constData(), dualData.length(), QHostAddress(QHostAddress::LocalHostIPv6), v6Sock.localPort()), dualData.length()); - QVERIFY(v6Sock.waitForReadyRead(5000)); + QVERIFY2(v6Sock.waitForReadyRead(5000), QtNetworkSettings::msgSocketError(v6Sock).constData()); buffer.reserve(100); size = v6Sock.readDatagram(buffer.data(), 100, &from, &port); QCOMPARE((int)size, dualData.length()); @@ -557,7 +558,7 @@ void tst_QUdpSocket::dualStackAutoBinding() QUdpSocket dualSock; QCOMPARE((int)dualSock.writeDatagram(dualData.constData(), dualData.length(), QHostAddress(QHostAddress::LocalHostIPv6), v6Sock.localPort()), dualData.length()); - QVERIFY(v6Sock.waitForReadyRead(5000)); + QVERIFY2(v6Sock.waitForReadyRead(5000), QtNetworkSettings::msgSocketError(v6Sock).constData()); buffer.reserve(100); size = v6Sock.readDatagram(buffer.data(), 100, &from, &port); QCOMPARE((int)size, dualData.length()); @@ -565,7 +566,7 @@ void tst_QUdpSocket::dualStackAutoBinding() QCOMPARE(buffer, dualData); QCOMPARE((int)dualSock.writeDatagram(dualData.constData(), dualData.length(), QHostAddress(QHostAddress::LocalHost), v4Sock.localPort()), dualData.length()); - QVERIFY(v4Sock.waitForReadyRead(5000)); + QVERIFY2(v4Sock.waitForReadyRead(5000), QtNetworkSettings::msgSocketError(v4Sock).constData()); buffer.reserve(100); size = v4Sock.readDatagram(buffer.data(), 100, &from, &port); QCOMPARE((int)size, dualData.length()); @@ -670,7 +671,7 @@ void tst_QUdpSocket::pendingDatagramSize() QVERIFY(client.writeDatagram("3 messages", 10, serverAddress, server.localPort()) == 10); char c = 0; - QVERIFY(server.waitForReadyRead()); + QVERIFY2(server.waitForReadyRead(), QtNetworkSettings::msgSocketError(server).constData()); if (server.hasPendingDatagrams()) { #if defined Q_OS_HPUX && defined __ia64 QEXPECT_FAIL("", "HP-UX 11i v2 can't determine the datagram size correctly.", Abort); @@ -1082,7 +1083,7 @@ void tst_QUdpSocket::zeroLengthDatagram() #endif QCOMPARE(sender.writeDatagram(QByteArray(), QHostAddress::LocalHost, receiver.localPort()), qint64(0)); - QVERIFY(receiver.waitForReadyRead(1000)); + QVERIFY2(receiver.waitForReadyRead(1000), QtNetworkSettings::msgSocketError(receiver).constData()); QVERIFY(receiver.hasPendingDatagrams()); char buf; @@ -1361,8 +1362,7 @@ void tst_QUdpSocket::multicast() int(datagram.size())); } - QVERIFY2(receiver.waitForReadyRead(), - qPrintable(receiver.errorString())); + QVERIFY2(receiver.waitForReadyRead(), QtNetworkSettings::msgSocketError(receiver).constData()); QVERIFY(receiver.hasPendingDatagrams()); QList<QByteArray> receivedDatagrams; while (receiver.hasPendingDatagrams()) { @@ -1428,7 +1428,7 @@ void tst_QUdpSocket::echo() qDebug() << "packets in" << successes << "out" << i; QTest::qWait(50); //choke to avoid triggering flood/DDoS protections on echo service } - QVERIFY(successes >= 9); + QVERIFY2(successes >= 9, QByteArray::number(successes).constData()); } void tst_QUdpSocket::linkLocalIPv6() @@ -1549,7 +1549,7 @@ void tst_QUdpSocket::linkLocalIPv4() QByteArray receiveBuffer("xxxxx"); foreach (QUdpSocket *s, sockets) { QVERIFY(s->writeDatagram(testData, s->localAddress(), neutral.localPort())); - QVERIFY(neutral.waitForReadyRead(10000)); + QVERIFY2(neutral.waitForReadyRead(10000), QtNetworkSettings::msgSocketError(neutral).constData()); QHostAddress from; quint16 fromPort; QCOMPARE((int)neutral.readDatagram(receiveBuffer.data(), receiveBuffer.length(), &from, &fromPort), testData.length()); @@ -1558,7 +1558,7 @@ void tst_QUdpSocket::linkLocalIPv4() QCOMPARE(receiveBuffer, testData); QVERIFY(neutral.writeDatagram(testData, s->localAddress(), s->localPort())); - QVERIFY(s->waitForReadyRead(10000)); + QVERIFY2(s->waitForReadyRead(10000), QtNetworkSettings::msgSocketError(*s).constData()); QCOMPARE((int)s->readDatagram(receiveBuffer.data(), receiveBuffer.length(), &from, &fromPort), testData.length()); QCOMPARE(receiveBuffer, testData); diff --git a/tests/auto/network/socket/qudpsocket/udpServer/main.cpp b/tests/auto/network/socket/qudpsocket/udpServer/main.cpp index e19e93dc18..a5986c29c7 100644 --- a/tests/auto/network/socket/qudpsocket/udpServer/main.cpp +++ b/tests/auto/network/socket/qudpsocket/udpServer/main.cpp @@ -31,18 +31,21 @@ class Server : public QObject { Q_OBJECT public: - Server(int port) + + Server() { connect(&serverSocket, &QIODevice::readyRead, this, &Server::sendEcho); } + + bool bind(quint16 port) { - connect(&serverSocket, SIGNAL(readyRead()), - this, SLOT(sendEcho())); - if (serverSocket.bind(QHostAddress::Any, port, - QUdpSocket::ReuseAddressHint - | QUdpSocket::ShareAddress)) { + const bool result = serverSocket.bind(QHostAddress::Any, port, + QUdpSocket::ReuseAddressHint + | QUdpSocket::ShareAddress); + if (result) { printf("OK\n"); } else { - printf("FAILED\n"); + printf("FAILED: %s\n", qPrintable(serverSocket.errorString())); } fflush(stdout); + return result; } private slots: @@ -68,8 +71,19 @@ private: int main(int argc, char **argv) { QCoreApplication app(argc, argv); + QStringList arguments = QCoreApplication::arguments(); + arguments.pop_front(); + quint16 port = 0; + if (!arguments.isEmpty()) + port = arguments.constFirst().toUShort(); + if (!port) { + printf("Specify port number\n"); + return -1; + } - Server server(app.arguments().at(1).toInt()); + Server server; + if (!server.bind(port)) + return -2; return app.exec(); } diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index f0e7cb5901..f2eaf6174e 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -69,7 +69,7 @@ #include "../../../qtest-config.h" -#if defined(Q_OS_MAC) +#if defined(Q_OS_OSX) #include "tst_qwidget_mac_helpers.h" // Abstract the ObjC stuff out so not everyone must run an ObjC++ compile. #endif @@ -136,7 +136,7 @@ bool qt_wince_is_smartphone() { } #endif -#ifdef Q_OS_MAC +#ifdef Q_OS_OSX #include <Security/AuthSession.h> bool macHasAccessToWindowsServer() { @@ -263,7 +263,7 @@ private slots: void restoreVersion1Geometry(); void widgetAt(); -#ifdef Q_OS_MAC +#ifdef Q_OS_OSX void sheetOpacity(); void setMask(); #endif @@ -296,7 +296,7 @@ private slots: void update(); void isOpaque(); -#ifndef Q_OS_MAC +#ifndef Q_OS_OSX void scroll(); void scrollNativeChildren(); #endif @@ -429,7 +429,7 @@ private slots: void taskQTBUG_7532_tabOrderWithFocusProxy(); void movedAndResizedAttributes(); void childAt(); -#ifdef Q_OS_MAC +#ifdef Q_OS_OSX void childAt_unifiedToolBar(); void taskQTBUG_11373(); #endif @@ -2375,12 +2375,12 @@ void tst_QWidget::showMinimizedKeepsFocus() window.showNormal(); qApp->setActiveWindow(&window); QVERIFY(QTest::qWaitForWindowActive(&window)); -#ifdef Q_OS_MAC +#ifdef Q_OS_OSX if (!macHasAccessToWindowsServer()) QEXPECT_FAIL("", "When not having WindowServer access, we lose focus.", Continue); #endif QTRY_COMPARE(window.focusWidget(), firstchild); -#ifdef Q_OS_MAC +#ifdef Q_OS_OSX if (!macHasAccessToWindowsServer()) QEXPECT_FAIL("", "When not having WindowServer access, we lose focus.", Continue); #endif @@ -2720,7 +2720,7 @@ public: void tst_QWidget::lostUpdatesOnHide() { -#ifndef Q_OS_MAC +#ifndef Q_OS_OSX UpdateWidget widget; widget.setAttribute(Qt::WA_DontShowOnScreen); widget.show(); @@ -2762,7 +2762,7 @@ void tst_QWidget::raise() QVERIFY(QTest::qWaitForWindowExposed(parentPtr.data())); QTest::qWait(10); -#ifdef Q_OS_MAC +#ifdef Q_OS_OSX if (child1->internalWinId()) { QSKIP("Cocoa has no Z-Order for views, we hack it, but it results in paint events."); } @@ -2942,7 +2942,7 @@ void tst_QWidget::stackUnder() foreach (UpdateWidget *child, allChildren) { int expectedPaintEvents = child == child4 ? 1 : 0; -#if defined(Q_OS_WIN) || defined(Q_OS_MAC) +#if defined(Q_OS_WIN) || defined(Q_OS_OSX) if (expectedPaintEvents == 1 && child->numPaintEvents == 2) QEXPECT_FAIL(0, "Mac and Windows issues double repaints for Z-Order change", Continue); #endif @@ -2981,7 +2981,7 @@ void tst_QWidget::stackUnder() #ifdef Q_OS_WINCE qApp->processEvents(); #endif -#ifndef Q_OS_MAC +#ifndef Q_OS_OSX QEXPECT_FAIL(0, "See QTBUG-493", Continue); #endif QCOMPARE(child->numPaintEvents, 0); @@ -3518,7 +3518,7 @@ void tst_QWidget::testDeletionInEventHandlers() delete w; } -#ifdef Q_OS_MAC +#ifdef Q_OS_OSX void tst_QWidget::sheetOpacity() { QWidget tmpWindow; @@ -4309,7 +4309,7 @@ void tst_QWidget::update() QCOMPARE(sibling.numPaintEvents, 1); QCOMPARE(sibling.paintedRegion, sibling.visibleRegion()); -#ifdef Q_OS_MAC +#ifdef Q_OS_OSX if (child.internalWinId()) // child is native QEXPECT_FAIL(0, "Cocoa compositor paints child and sibling", Continue); #endif @@ -4335,7 +4335,7 @@ static inline bool isOpaque(QWidget *widget) void tst_QWidget::isOpaque() { -#ifndef Q_OS_MAC +#ifndef Q_OS_OSX QWidget w; QVERIFY(::isOpaque(&w)); @@ -4407,7 +4407,7 @@ void tst_QWidget::isOpaque() #endif } -#ifndef Q_OS_MAC +#ifndef Q_OS_OSX /* Test that scrolling of a widget invalidates the correct regions */ @@ -4854,7 +4854,7 @@ void tst_QWidget::windowMoveResize() widget.move(r.topLeft()); widget.resize(r.size()); QApplication::processEvents(); -#if defined(Q_OS_MAC) +#if defined(Q_OS_OSX) if (r.width() == 0 && r.height() > 0) { widget.move(r.topLeft()); widget.resize(r.size()); @@ -4925,7 +4925,7 @@ void tst_QWidget::windowMoveResize() widget.move(r.topLeft()); widget.resize(r.size()); QApplication::processEvents(); -#if defined(Q_OS_MAC) +#if defined(Q_OS_OSX) if (r.width() == 0 && r.height() > 0) { widget.move(r.topLeft()); widget.resize(r.size()); @@ -5115,7 +5115,7 @@ void tst_QWidget::moveChild() QTRY_COMPARE(pos, child.pos()); QCOMPARE(parent.r, QRegion(oldGeometry) - child.geometry()); -#if !defined(Q_OS_MAC) +#if !defined(Q_OS_OSX) // should be scrolled in backingstore QCOMPARE(child.r, QRegion()); #endif @@ -5857,7 +5857,7 @@ public: startTimer(1000); } - void timerEvent(QTimerEvent *) + void timerEvent(QTimerEvent *) Q_DECL_OVERRIDE { switch (state++) { case 0: @@ -5880,7 +5880,7 @@ public: return false; } - bool nativeEvent(const QByteArray &eventType, void *message, long *) + bool nativeEvent(const QByteArray &eventType, void *message, long *) Q_DECL_OVERRIDE { if (isMapNotify(eventType, message)) gotExpectedMapNotify = true; @@ -5888,7 +5888,7 @@ public: } // QAbstractNativeEventFilter interface - virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long *) Q_DECL_OVERRIDE + bool nativeEventFilter(const QByteArray &eventType, void *message, long *) Q_DECL_OVERRIDE { if (isMapNotify(eventType, message)) gotExpectedGlobalEvent = true; @@ -6907,7 +6907,7 @@ void tst_QWidget::render_systemClip() // rrrrrrrrrr // ... -#ifndef Q_OS_MAC +#ifndef Q_OS_OSX for (int i = 0; i < image.height(); ++i) { for (int j = 0; j < image.width(); ++j) { if (i < 50 && j < i) @@ -7911,7 +7911,7 @@ void tst_QWidget::sendUpdateRequestImmediately() void tst_QWidget::doubleRepaint() { -#if defined(Q_OS_MAC) +#if defined(Q_OS_OSX) if (!macHasAccessToWindowsServer()) QSKIP("Not having window server access causes the wrong number of repaints to be issues"); #endif @@ -8621,7 +8621,7 @@ void tst_QWidget::setClearAndResizeMask() QTRY_COMPARE(child.mask(), childMask); QTest::qWait(50); // and ensure that the child widget doesn't get any update. -#ifdef Q_OS_MAC +#ifdef Q_OS_OSX // Mac always issues a full update when calling setMask, and we cannot force it to not do so. if (child.internalWinId()) QCOMPARE(child.numPaintEvents, 1); @@ -8644,7 +8644,7 @@ void tst_QWidget::setClearAndResizeMask() // and ensure that that the child widget gets an update for the area outside the old mask. QTRY_COMPARE(child.numPaintEvents, 1); outsideOldMask = child.rect(); -#ifdef Q_OS_MAC +#ifdef Q_OS_OSX // Mac always issues a full update when calling setMask, and we cannot force it to not do so. if (!child.internalWinId()) #endif @@ -8659,7 +8659,7 @@ void tst_QWidget::setClearAndResizeMask() // Mask child widget with a mask that is bigger than the rect child.setMask(QRegion(0, 0, 1000, 1000)); QTest::qWait(100); -#ifdef Q_OS_MAC +#ifdef Q_OS_OSX // Mac always issues a full update when calling setMask, and we cannot force it to not do so. if (child.internalWinId()) QTRY_COMPARE(child.numPaintEvents, 1); @@ -8672,7 +8672,7 @@ void tst_QWidget::setClearAndResizeMask() // ...and the same applies when clearing the mask. child.clearMask(); QTest::qWait(100); -#ifdef Q_OS_MAC +#ifdef Q_OS_OSX // Mac always issues a full update when calling setMask, and we cannot force it to not do so. if (child.internalWinId()) QTRY_VERIFY(child.numPaintEvents > 0); @@ -8702,7 +8702,7 @@ void tst_QWidget::setClearAndResizeMask() QTimer::singleShot(100, &resizeChild, SLOT(shrinkMask())); QTest::qWait(200); -#ifdef Q_OS_MAC +#ifdef Q_OS_OSX // Mac always issues a full update when calling setMask, and we cannot force it to not do so. if (child.internalWinId()) QTRY_COMPARE(resizeChild.paintedRegion, resizeChild.mask()); @@ -8714,7 +8714,7 @@ void tst_QWidget::setClearAndResizeMask() const QRegion oldMask = resizeChild.mask(); QTimer::singleShot(0, &resizeChild, SLOT(enlargeMask())); QTest::qWait(100); -#ifdef Q_OS_MAC +#ifdef Q_OS_OSX // Mac always issues a full update when calling setMask, and we cannot force it to not do so. if (child.internalWinId()) QTRY_COMPARE(resizeChild.paintedRegion, resizeChild.mask()); @@ -9427,7 +9427,7 @@ void tst_QWidget::taskQTBUG_7532_tabOrderWithFocusProxy() void tst_QWidget::movedAndResizedAttributes() { -#if defined (Q_OS_MAC) +#if defined (Q_OS_OSX) QEXPECT_FAIL("", "FixMe, QTBUG-8941 and QTBUG-8977", Abort); QVERIFY(false); #else @@ -9534,7 +9534,7 @@ void tst_QWidget::childAt() QCOMPARE(parent.childAt(120, 120), grandChild); } -#ifdef Q_OS_MAC +#ifdef Q_OS_OSX void tst_QWidget::childAt_unifiedToolBar() { QLabel *label = new QLabel(QLatin1String("foo")); diff --git a/tests/manual/textrendering/glyphshaping/glyphshaping.pro b/tests/manual/textrendering/glyphshaping/glyphshaping.pro index 6500814423..f4e0b45734 100644 --- a/tests/manual/textrendering/glyphshaping/glyphshaping.pro +++ b/tests/manual/textrendering/glyphshaping/glyphshaping.pro @@ -1,6 +1,5 @@ QT += widgets SOURCES = main.cpp -OTHER_FILES = glyphshaping_data.xml glyphshaping_data.path = . glyphshaping_data.files = $$PWD/glyphshaping_data.xml DEPLOYMENT += glyphshaping_data diff --git a/tests/manual/touch/main.cpp b/tests/manual/touch/main.cpp index fb0c8559f9..66ad02f78b 100644 --- a/tests/manual/touch/main.cpp +++ b/tests/manual/touch/main.cpp @@ -256,6 +256,9 @@ QColor Point::color() const case Qt::MouseEventSynthesizedByQt: globalColor = Qt::blue; break; + case Qt::MouseEventSynthesizedByApplication: + globalColor = Qt::green; + break; case Qt::MouseEventNotSynthesized: break; } diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 9a4602715b..5cd1928f65 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -1651,6 +1651,7 @@ void Configure::applySpecSpecifics() dictionary["DECORATIONS"] = "default windows styled"; } else if (platform() == QNX) { + dictionary[ "REDUCE_EXPORTS" ] = "yes"; dictionary["STACK_PROTECTOR_STRONG"] = "auto"; dictionary["SLOG2"] = "auto"; dictionary["QNX_IMF"] = "auto"; @@ -1660,6 +1661,7 @@ void Configure::applySpecSpecifics() dictionary[ "ANGLE" ] = "no"; dictionary[ "DYNAMICGL" ] = "no"; dictionary[ "FONT_CONFIG" ] = "auto"; + dictionary[ "ICU" ] = "auto"; dictionary[ "POLL" ] = "poll"; } else if (platform() == ANDROID) { dictionary[ "REDUCE_EXPORTS" ] = "yes"; |