Merge remote-tracking branch 'origin/5.10' into dev

Conflicts:
	src/corelib/thread/qsemaphore.cpp
	tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
	tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp

Change-Id: Id35b535e88df63fdfe4007ea92ed4a39c4b6d707
This commit is contained in:
Liang Qi 2017-11-30 08:28:20 +01:00
commit 87204c856a
93 changed files with 1154 additions and 953 deletions

1
.gitignore vendored
View File

@ -245,6 +245,7 @@ tags
*.gcda
*.gcno
*.lib
!Info.plist.lib
*.o
*.obj
*.orig

View File

@ -82,7 +82,7 @@ Build options:
-debug-and-release ... Build two versions of Qt, with and without
debugging turned on [yes] (Apple and Windows only)
-optimize-debug ...... Enable debug-friendly optimizations in debug builds
[auto] (Not supported with MSVC)
[auto] (Not supported with MSVC or Clang toolchains)
-optimize-size ....... Optimize release builds for size instead of speed [no]
-optimized-tools ..... Build optimized host tools even in debug build [no]
-force-debug-info .... Create symbol files for release builds [no]

View File

@ -703,7 +703,7 @@
},
"optimize_debug": {
"label": "Optimize debug build",
"condition": "!config.msvc && (features.debug || features.debug_and_release) && tests.optimize_debug",
"condition": "!config.msvc && !config.clang && (features.debug || features.debug_and_release) && tests.optimize_debug",
"output": [ "privateConfig" ]
},
"optimize_size": {
@ -1344,7 +1344,7 @@ Configure with '-qreal float' to create a build that is binary-compatible with 5
{
"type": "feature",
"args": "optimize_debug",
"condition": "!config.msvc && (features.debug || features.debug_and_release)"
"condition": "!config.msvc && !config.clang && (features.debug || features.debug_and_release)"
},
{
"type": "feature",

144
dist/changes-5.9.3 vendored Normal file
View File

@ -0,0 +1,144 @@
Qt 5.9.3 is a bug-fix release. It maintains both forward and backward
compatibility (source and binary) with Qt 5.9.0 through 5.9.2.
For more details, refer to the online documentation included in this
distribution. The documentation is also available online:
http://doc.qt.io/qt-5/index.html
The Qt version 5.9 series is binary compatible with the 5.8.x series.
Applications compiled for 5.8 will continue to run with 5.9.
Some of the changes listed in this file include issue tracking numbers
corresponding to tasks in the Qt Bug Tracker:
https://bugreports.qt.io/
Each of these identifiers can be entered in the bug tracker to obtain more
information about a particular change.
****************************************************************************
* Qt 5.9.3 Changes *
****************************************************************************
QtCore
------
- QFileSystemWatcher:
* [QTBUG-64171] Fixed a bug that would cause the application to crash if
QFileSystemWatcher was created in an auxiliary thread on Windows.
- QStorageInfo:
* [QTBUG-61420] Fixed decoding of volume labels containing certain
uncommon characters on Linux.
- QThreadPool:
* Improved performance with large amount of QRunnable items.
QtGui
------
- [QTBUG-64239] Fixed memory corruption on scaled emojis.
- [QTBUG-63846] Fixed dragging inside a modal window when a
QShapedPixmapWindow is used.
- [QTBUG-61777] Fixed painting of zero-length lines with scaling.
- [QTBUG-61244] Fixed centering of some items in layouts.
- [QTBUG-63168] Fixed a crash when reparenting QWindowContainer.
QtNetwork
---------
- QHostAddress:
* [QTBUG-63764] Fixed a problem in QHostAddress not detaching in its
setters and thus spoiling shared data.
- QNetworkAccessManager:
* [QTBUG-63075] Added support for HTTP status 308.
* [QTBUG-61300] Fixed a problem with mixing headers from different
responses.
* [QTBUG-63471] Fixed redirects support in HTTP/2 protocol handler.
* [QTBUG-63313] Fixed cookies received during a redirect not being
applied in the redirect.
* [QTBUG-63142] Fixed HTTP method always being changed to GET when
redirected with 307 and 308.
- QNetworkCookieJar:
* Fixed cookies with a root path ("/") not matching an empty path ("").
QtSql
------
- PostgreSQL:
* Fixed handling of binary data for PostgreSQL 9.x and later
* Fixed detection of PostgreSQL 9.x and later
- OCI:
* [QTBUG-57765] Fixed a bug that would see some cached results returned
when issuing a forward only query
QtWidgets
---------
- QAction:
* [QTBUG-62006] Ensured setData() does not emit changed() if no change
happened.
- QDockWidget:
* [QTBUG-63526] Fixed an issue in QDockWidgets where the widget would
not resize despite showing a resize cursor.
- QHeaderView:
* [QTBUG-54601] Fixed resizing when hidden sections were involved.
* [QTBUG-64036] Ensured maximumSectionSize property is honored during
resizeSections().
- QListView:
* [QTBUG-45427] Fixed the laying out of a QListView in a grid layout
after the dataChanged() signal is emitted.
- QMenuBar
* [QTBUG-34160] Fixed a problem with adding the same QAction to more than
one menu.
- QWidget
* [QTBUG-56860] Fixed widget losing focus after showing menu second time.
- QWizard:
* [QTBUG-46894] Fixed the shortcut for the Next button on Windows.
Platform-specific changes
-------------------------
- Cocoa:
* optimize backingstore flush on 10-bit displays
* [QTBUG-57076] [QTBUG-63712] Attach menu items when updating the menubar
* [QTBUG-63444] Toggle titlebar transparency to support unified toolbar
- iOS:
* [QTBUG-57428][QTBUG-63660] add support for adding mimetypes other than text
on the clipboard
- Windows:
* [QTBUG-63654] Windows font database: Remove clamping of default font size
- X11:
* [QTBUG-48034] Don't misdetect certain trackballs as tablets
* [QTBUG-62840] Fix crash on X servers with BGR888 display
Third-Party Code
----------------
- Improved documentation about Freetype 2 licenses.
- Updated Sqlite to fix CVE-2017-10989.
- Updated bundled libpng to version 1.6.34.
Tools
-----
* qmake:
- [QTBUG-63409] Fixed a build error with MSVC when concrt.h was included
while exceptions are disabled.
- [QTBUG-62985] Fixed a bug that caused the accidental creation of files
called "NUL" when using MinGW.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -2,7 +2,6 @@ TEMPLATE = \
subdirs
SUBDIRS += \
animatedtiles \
appchooser \
easing \
moveblocks \
states \

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

View File

@ -1,8 +0,0 @@
QT += widgets
SOURCES = main.cpp
RESOURCES = appchooser.qrc
# install
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/animation/appchooser
INSTALLS += target

View File

@ -1,8 +0,0 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file>accessories-dictionary.png</file>
<file>akregator.png</file>
<file>digikam.png</file>
<file>k3b.png</file>
</qresource>
</RCC>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.0 KiB

View File

@ -1,183 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtCore>
#include <QtWidgets>
class Pixmap : public QGraphicsWidget
{
Q_OBJECT
public:
Pixmap(const QPixmap &pix, QGraphicsItem *parent = 0)
: QGraphicsWidget(parent), orig(pix), p(pix)
{
}
void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) override
{
painter->drawPixmap(QPointF(), p);
}
void mousePressEvent(QGraphicsSceneMouseEvent *) override
{
emit clicked();
}
void setGeometry(const QRectF &rect) override
{
QGraphicsWidget::setGeometry(rect);
if (rect.size().width() > orig.size().width())
p = orig.scaled(rect.size().toSize());
else
p = orig;
}
Q_SIGNALS:
void clicked();
private:
QPixmap orig;
QPixmap p;
};
class GraphicsView : public QGraphicsView
{
Q_OBJECT
public:
GraphicsView(QGraphicsScene *scene, QWidget *parent = 0) : QGraphicsView(scene, parent)
{
}
void resizeEvent(QResizeEvent *) override
{
fitInView(sceneRect(), Qt::KeepAspectRatio);
}
};
void createStates(const QObjectList &objects,
const QRect &selectedRect, QState *parent)
{
for (int i = 0; i < objects.size(); ++i) {
QState *state = new QState(parent);
state->assignProperty(objects.at(i), "geometry", selectedRect);
parent->addTransition(objects.at(i), SIGNAL(clicked()), state);
}
}
void createAnimations(const QObjectList &objects, QStateMachine *machine)
{
for (int i=0; i<objects.size(); ++i)
machine->addDefaultAnimation(new QPropertyAnimation(objects.at(i), "geometry"));
}
int main(int argc, char **argv)
{
Q_INIT_RESOURCE(appchooser);
QApplication app(argc, argv);
Pixmap *p1 = new Pixmap(QPixmap(":/digikam.png"));
Pixmap *p2 = new Pixmap(QPixmap(":/akregator.png"));
Pixmap *p3 = new Pixmap(QPixmap(":/accessories-dictionary.png"));
Pixmap *p4 = new Pixmap(QPixmap(":/k3b.png"));
p1->setObjectName("p1");
p2->setObjectName("p2");
p3->setObjectName("p3");
p4->setObjectName("p4");
p1->setGeometry(QRectF( 0.0, 0.0, 64.0, 64.0));
p2->setGeometry(QRectF(236.0, 0.0, 64.0, 64.0));
p3->setGeometry(QRectF(236.0, 236.0, 64.0, 64.0));
p4->setGeometry(QRectF( 0.0, 236.0, 64.0, 64.0));
QGraphicsScene scene(0, 0, 300, 300);
scene.setBackgroundBrush(Qt::white);
scene.addItem(p1);
scene.addItem(p2);
scene.addItem(p3);
scene.addItem(p4);
GraphicsView window(&scene);
window.setFrameStyle(0);
window.setAlignment(Qt::AlignLeft | Qt::AlignTop);
window.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
window.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
QStateMachine machine;
machine.setGlobalRestorePolicy(QState::RestoreProperties);
QState *group = new QState(&machine);
group->setObjectName("group");
QRect selectedRect(86, 86, 128, 128);
QState *idleState = new QState(group);
group->setInitialState(idleState);
QObjectList objects;
objects << p1 << p2 << p3 << p4;
createStates(objects, selectedRect, group);
createAnimations(objects, &machine);
machine.setInitialState(group);
machine.start();
window.resize(300, 300);
window.show();
return app.exec();
}
#include "main.moc"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -1,38 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:FDL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Free Documentation License Usage
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of
** this file. Please review the following information to ensure
** the GNU Free Documentation License version 1.3 requirements
** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
** $QT_END_LICENSE$
**
****************************************************************************/
/*!
\example animation/appchooser
\title Application Chooser Example
\brief The Application Chooser example shows how to use the Qt state
machine and the animation framework to select between
applications.
\image appchooser-example.png
*/

View File

@ -75,7 +75,7 @@
QSortFilterProxyModel's default implementations of functions are
written so that they call the equivalent functions in the relevant
source model. This simple proxying mechanism may need to be
overridden for source models with more complex behavior; in this
overridden for source models with more complex behavior. In this
example we derive from the QSortFilterProxyModel class to ensure
that our filter can recognize a valid range of dates, and to
control the sorting behavior.
@ -170,7 +170,7 @@
We implement two private slots, \c textFilterChanged() and \c
dateFilterChanged(), to respond to the user changing the filter
pattern, case sensitivity or any of the dates. In addition, we
pattern, case sensitivity, or any of the dates. In addition, we
implement a public \c setSourceModel() convenience function to set
up the model/ view relation.
@ -197,7 +197,7 @@
\snippet itemviews/customsortfiltermodel/window.cpp 1
The QTreeView class provides a default model/view implementation
of a tree view; our view implements a tree representation of items
of a tree view. Our view implements a tree representation of items
in the application's source model.
\snippet itemviews/customsortfiltermodel/window.cpp 2

View File

@ -1,35 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:FDL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Free Documentation License Usage
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of
** this file. Please review the following information to ensure
** the GNU Free Documentation License version 1.3 requirements
** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
** $QT_END_LICENSE$
**
****************************************************************************/
/*!
\example effects/lighting
\title Lighting Effect Example
\ingroup examples-graphicsview-graphicseffects
\brief Demonstrates how to apply effects on items in the view
\image lightingeffect-example.png
*/

View File

@ -37,7 +37,7 @@
When displaying data in a QListView, QTableView, or QTreeView,
the individual items are drawn by a
\l{Delegate Classes}{delegate}. Also, when the user starts
editing an item (e.g., by double-clicking the item), the delegate
editing an item (for example, by double-clicking the item), the delegate
provides an editor widget that is placed on top of the item while
editing takes place.
@ -96,9 +96,9 @@
QItemDelegate paint it for us. This ensures that the \c
StarDelegate can handle the most common data types.
In the case where the item is a \c StarRating, we draw the
background if the item is selected, and we draw the item using \c
StarRating::paint(), which we will review later.
If the item is a \c StarRating, we draw the background if the
item is selected, and we draw the item using \c StarRating::paint(),
which we will review later.
\c{StartRating}s can be stored in a QVariant thanks to the
Q_DECLARE_METATYPE() macro appearing in \c starrating.h. More on
@ -133,8 +133,8 @@
We simply call \c setStarRating() on the editor.
The \l{QAbstractItemDelegate::}{setModelData()} function is
called when editing is finished, to commit data from the editor
to the model:
called to commit data from the editor to the model when editing
is finished:
\snippet itemviews/stardelegate/stardelegate.cpp 4
@ -210,7 +210,7 @@
current rating, and \c myMaxStarCount stores the highest possible
rating (typically 5).
The Q_DECLARE_METATYPE() macro makes the type \c StarRating known
The \c Q_DECLARE_METATYPE() macro makes the type \c StarRating known
to QVariant, making it possible to store \c StarRating values in
QVariant.
@ -283,7 +283,7 @@
\list
\li It is possible to open editors programmatically by calling
QAbstractItemView::edit(), instead of relying on edit
triggers. This could be use to support other edit triggers
triggers. This could be used to support other edit triggers
than those offered by the QAbstractItemView::EditTrigger enum.
For example, in the Star Delegate example, hovering over an
item with the mouse might make sense as a way to pop up an

View File

@ -33,5 +33,56 @@
\borderedimage stylesheet-pagefold.png
\caption Screen Shot of the Pagefold style sheet
The Style Sheet example shows how widgets can be styled using Qt Style Sheets.
You can open the style editor by selecting \uicontrol File > \uicontrol Edit Style Sheet,
to select an existing style sheet or design your own style and load it.
The Style Sheet example consists of 2 classes:
\list
\li \c MainWindow
\li \c StyleSheetEditor
\endlist
\section1 MainWindow Class
\c MainWindow inherits QWidget, and is the application's main window defined in
\c mainwindow.ui. The style of \c MainWindow can be modified with \l StyleSheetEditor.
\section1 StyleSheetEditor Class
\c StyleSheetEditor enables you to open an editor where you can load an existing style sheet.
It is also possible to define a new stylesheet and load it. Its layout is defined in
\c stylesheeteditor.ui.
\quotefromfile widgets/stylesheet/stylesheeteditor.cpp
\skipto on_styleCombo_activated
\printline on_styleCombo_activated
Sets the specified \a styleName and grays the \c applyButton.
\skipto on_styleSheetCombo_activated
\printline on_styleSheetCombo_activated
Loads the stylesheet from \c styleSheetName.
\skipto on_styleTextEdit_textChanged()
\printline on_styleTextEdit_textChanged()
Enables the \c applyButton when the text in the buffer has changed.
\skipto on_applyButton_clicked()
\printline on_applyButton_clicked()
Sets the stylesheet properties in \l qApp and disables the \c applyButton.
\skipto loadStyleSheet(const QString &sheetName)
\printline loadStyleSheet(const QString &sheetName)
Loads the specified \a sheetName, and sets its properties in
\l qApp.
*/

View File

@ -31,4 +31,6 @@
\ingroup examples-widgets
\brief The Validators example shows the signal emission behavior of input
validators.
\borderedimage validators.png
*/

View File

@ -2,5 +2,4 @@ TEMPLATE = \
subdirs
SUBDIRS = \
blurpicker \
lighting \
fademessage

View File

@ -1,145 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "lighting.h"
#include <QtWidgets>
#include <QtCore/qmath.h>
Lighting::Lighting(QWidget *parent): QGraphicsView(parent), angle(0.0)
{
setScene(&m_scene);
setupScene();
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), SLOT(animate()));
timer->setInterval(30);
timer->start();
setRenderHint(QPainter::Antialiasing, true);
setFrameStyle(QFrame::NoFrame);
}
void Lighting::setupScene()
{
m_scene.setSceneRect(-300, -200, 600, 460);
QLinearGradient linearGrad(QPointF(-100, -100), QPointF(100, 100));
linearGrad.setColorAt(0, QColor(255, 255, 255));
linearGrad.setColorAt(1, QColor(192, 192, 255));
setBackgroundBrush(linearGrad);
QRadialGradient radialGrad(30, 30, 30);
radialGrad.setColorAt(0, Qt::yellow);
radialGrad.setColorAt(0.2, Qt::yellow);
radialGrad.setColorAt(1, Qt::transparent);
QPixmap pixmap(60, 60);
pixmap.fill(Qt::transparent);
QPainter painter(&pixmap);
painter.setPen(Qt::NoPen);
painter.setBrush(radialGrad);
painter.drawEllipse(0, 0, 60, 60);
painter.end();
m_lightSource = m_scene.addPixmap(pixmap);
m_lightSource->setZValue(2);
for (int i = -2; i < 3; ++i)
for (int j = -2; j < 3; ++j) {
QAbstractGraphicsShapeItem *item;
if ((i + j) & 1)
item = new QGraphicsEllipseItem(0, 0, 50, 50);
else
item = new QGraphicsRectItem(0, 0, 50, 50);
item->setPen(QPen(Qt::black, 1));
item->setBrush(QBrush(Qt::white));
QGraphicsDropShadowEffect *effect = new QGraphicsDropShadowEffect;
effect->setBlurRadius(8);
item->setGraphicsEffect(effect);
item->setZValue(1);
item->setPos(i * 80, j * 80);
m_scene.addItem(item);
m_items << item;
}
}
void Lighting::animate()
{
angle += qDegreesToRadians(qreal(6));
qreal xs = 200 * qSin(angle) - 40 + 25;
qreal ys = 200 * qCos(angle) - 40 + 25;
m_lightSource->setPos(xs, ys);
for (int i = 0; i < m_items.size(); ++i) {
QGraphicsItem *item = m_items.at(i);
Q_ASSERT(item);
QGraphicsDropShadowEffect *effect = static_cast<QGraphicsDropShadowEffect *>(item->graphicsEffect());
Q_ASSERT(effect);
QPointF delta(item->x() - xs, item->y() - ys);
effect->setOffset(delta.toPoint() / 30);
qreal dx = delta.x();
qreal dy = delta.y();
qreal dd = qSqrt(dx * dx + dy * dy);
QColor color = effect->color();
color.setAlphaF(qBound(0.4, 1 - dd / 200.0, 0.7));
effect->setColor(color);
}
m_scene.update();
}
void Lighting::resizeEvent(QResizeEvent * /* event */)
{
}

View File

@ -1,80 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef LIGHTING_H
#define LIGHTING_H
#include <QGraphicsEffect>
#include <QGraphicsView>
class Lighting: public QGraphicsView
{
Q_OBJECT
public:
Lighting(QWidget *parent = 0);
private slots:
void animate();
private:
void setupScene();
protected:
void resizeEvent(QResizeEvent *event) override;
private:
qreal angle;
QGraphicsScene m_scene;
QGraphicsItem *m_lightSource;
QList<QGraphicsItem*> m_items;
};
#endif // LIGHTING_H

View File

@ -1,8 +0,0 @@
QT += widgets
SOURCES += main.cpp lighting.cpp
HEADERS += lighting.h
# install
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/effects/lighting
INSTALLS += target

View File

@ -1,65 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "lighting.h"
#include <QApplication>
int main(int argc, char **argv)
{
QApplication app(argc, argv);
Lighting lighting;
lighting.setWindowTitle(QT_TRANSLATE_NOOP(QGraphicsView, "Lighting and Shadows"));
lighting.resize(640, 480);
lighting.show();
return app.exec();
}

View File

@ -77,8 +77,8 @@ XFormView::XFormView(QWidget *parent)
pts->setBoundingRect(QRectF(0, 0, 500, 500));
ctrlPoints << QPointF(250, 250) << QPointF(350, 250);
pts->setPoints(ctrlPoints);
connect(pts, SIGNAL(pointsChanged(QPolygonF)),
this, SLOT(updateCtrlPoints(QPolygonF)));
connect(pts, &HoverPoints::pointsChanged,
this,&XFormView::updateCtrlPoints);
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
}
@ -876,29 +876,29 @@ XFormWidget::XFormWidget(QWidget *parent)
#endif
mainGroupLayout->addWidget(whatsThisButton);
connect(rotateSlider, SIGNAL(valueChanged(int)), view, SLOT(changeRotation(int)));
connect(shearSlider, SIGNAL(valueChanged(int)), view, SLOT(changeShear(int)));
connect(scaleSlider, SIGNAL(valueChanged(int)), view, SLOT(changeScale(int)));
connect(rotateSlider, &QSlider::valueChanged, view, &XFormView::changeRotation);
connect(shearSlider, &QSlider::valueChanged, view, &XFormView::changeShear);
connect(scaleSlider, &QSlider::valueChanged, view, &XFormView::changeScale);
connect(vectorType, SIGNAL(clicked()), view, SLOT(setVectorType()));
connect(pixmapType, SIGNAL(clicked()), view, SLOT(setPixmapType()));
connect(textType, SIGNAL(clicked()), view, SLOT(setTextType()));
connect(textType, SIGNAL(toggled(bool)), textEditor, SLOT(setEnabled(bool)));
connect(textEditor, SIGNAL(textChanged(QString)), view, SLOT(setText(QString)));
connect(vectorType, &QRadioButton::clicked, view, &XFormView::setVectorType);
connect(pixmapType, &QRadioButton::clicked, view, &XFormView::setPixmapType);
connect(textType, &QRadioButton::clicked, view, &XFormView::setTextType);
connect(textType, &QRadioButton::toggled, textEditor, &XFormView::setEnabled);
connect(textEditor, &QLineEdit::textChanged, view, &XFormView::setText);
connect(view, SIGNAL(rotationChanged(int)), rotateSlider, SLOT(setValue(int)));
connect(view, SIGNAL(scaleChanged(int)), scaleSlider, SLOT(setValue(int)));
connect(view, SIGNAL(shearChanged(int)), shearSlider, SLOT(setValue(int)));
connect(view, &XFormView::rotationChanged, rotateSlider, &QSlider::setValue);
connect(view, &XFormView::scaleChanged, scaleSlider, &QAbstractSlider::setValue);
connect(view, &XFormView::shearChanged, shearSlider, &QAbstractSlider::setValue);
connect(resetButton, SIGNAL(clicked()), view, SLOT(reset()));
connect(animateButton, SIGNAL(clicked(bool)), view, SLOT(setAnimation(bool)));
connect(whatsThisButton, SIGNAL(clicked(bool)), view, SLOT(setDescriptionEnabled(bool)));
connect(whatsThisButton, SIGNAL(clicked(bool)), view->hoverPoints(), SLOT(setDisabled(bool)));
connect(view, SIGNAL(descriptionEnabledChanged(bool)), view->hoverPoints(), SLOT(setDisabled(bool)));
connect(view, SIGNAL(descriptionEnabledChanged(bool)), whatsThisButton, SLOT(setChecked(bool)));
connect(showSourceButton, SIGNAL(clicked()), view, SLOT(showSource()));
connect(resetButton, &QPushButton::clicked, view, &XFormView::reset);
connect(animateButton, &QPushButton::clicked, view, &XFormView::setAnimation);
connect(whatsThisButton, &QPushButton::clicked, view, &ArthurFrame::setDescriptionEnabled);
connect(whatsThisButton, &QPushButton::clicked, view->hoverPoints(), &HoverPoints::setDisabled);
connect(view, &XFormView::descriptionEnabledChanged, view->hoverPoints(), &HoverPoints::setDisabled);
connect(view, &XFormView::descriptionEnabledChanged, whatsThisButton, &QPushButton::setChecked);
connect(showSourceButton, &QPushButton::clicked, view, &XFormView::showSource);
#ifdef QT_OPENGL_SUPPORT
connect(enableOpenGLButton, SIGNAL(clicked(bool)), view, SLOT(enableOpenGL(bool)));
connect(enableOpenGLButton, &QPushButton::clicked, view, &XFormView::enableOpenGL);
#endif
view->loadSourceFile(":res/affine/xform.cpp");
view->loadDescription(":res/affine/xform.html");

View File

@ -60,6 +60,7 @@ MainWindow::MainWindow(TabletCanvas *canvas)
createMenus();
setWindowTitle(tr("Tablet Example"));
setCentralWidget(m_canvas);
QCoreApplication::setAttribute(Qt::AA_CompressHighFrequencyEvents);
}
//! [0]
@ -97,6 +98,11 @@ void MainWindow::setSaturationValuator(QAction *action)
}
//! [4]
void MainWindow::setEventCompression(bool compress)
{
QCoreApplication::setAttribute(Qt::AA_CompressTabletEvents, compress);
}
//! [5]
void MainWindow::save()
{
@ -220,6 +226,10 @@ void MainWindow::createMenus()
connect(colorSaturationGroup, &QActionGroup::triggered,
this, &MainWindow::setSaturationValuator);
QAction *compressAction = tabletMenu->addAction(tr("Co&mpress events"));
compressAction->setCheckable(true);
connect(compressAction, &QAction::toggled, this, &MainWindow::setEventCompression);
QMenu *helpMenu = menuBar()->addMenu("&Help");
helpMenu->addAction(tr("A&bout"), this, &MainWindow::about);
helpMenu->addAction(tr("About &Qt"), qApp, &QApplication::aboutQt);

View File

@ -71,6 +71,7 @@ private slots:
void setAlphaValuator(QAction *action);
void setLineWidthValuator(QAction *action);
void setSaturationValuator(QAction *action);
void setEventCompression(bool compress);
void save();
void load();
void about();

View File

@ -723,184 +723,189 @@ public class QtActivityDelegate
Bundle extras = m_activity.getIntent().getExtras();
if (extras != null) {
if ( /*(ai.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0
&&*/ extras.containsKey("debug_ping")
&& extras.getString("debug_ping").equals("true")) {
try {
final String dc = "--Added-by-androiddeployqt--/debugger.command";
String debuggerCommand =
new BufferedReader(new InputStreamReader(m_activity.getAssets().open(dc))).readLine();
String packagePath =
m_activity.getPackageManager().getApplicationInfo(m_activity.getPackageName(),
PackageManager.GET_CONFIGURATIONS).dataDir + "/";
try {
final String dc = "--Added-by-androiddeployqt--/debugger.command";
String debuggerCommand =
new BufferedReader(new InputStreamReader(m_activity.getAssets().open(dc))).readLine();
if ( /*(ai.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0
&&*/ extras.containsKey("debug_ping")
&& extras.getString("debug_ping").equals("true")) {
try {
String packagePath =
m_activity.getPackageManager().getApplicationInfo(m_activity.getPackageName(),
PackageManager.GET_CONFIGURATIONS).dataDir + "/";
debugLog("extra parameters: " + extras);
String packageName = m_activity.getPackageName();
String pingFile = extras.getString("ping_file");
String pongFile = extras.getString("pong_file");
String gdbserverSocket = extras.getString("gdbserver_socket");
String gdbserverCommand = packagePath + debuggerCommand + gdbserverSocket;
String pingSocket = extras.getString("ping_socket");
boolean usePing = pingFile != null;
boolean usePong = pongFile != null;
boolean useSocket = gdbserverSocket != null;
boolean usePingSocket = pingSocket != null;
int napTime = 200; // milliseconds between file accesses
int timeOut = 30000; // ms until we give up on ping and pong
int maxAttempts = timeOut / napTime;
debugLog("extra parameters: " + extras);
String packageName = m_activity.getPackageName();
String pingFile = extras.getString("ping_file");
String pongFile = extras.getString("pong_file");
String gdbserverSocket = extras.getString("gdbserver_socket");
String gdbserverCommand = packagePath + debuggerCommand + gdbserverSocket;
String pingSocket = extras.getString("ping_socket");
boolean usePing = pingFile != null;
boolean usePong = pongFile != null;
boolean useSocket = gdbserverSocket != null;
boolean usePingSocket = pingSocket != null;
int napTime = 200; // milliseconds between file accesses
int timeOut = 30000; // ms until we give up on ping and pong
int maxAttempts = timeOut / napTime;
if (gdbserverSocket != null) {
debugLog("removing gdb socket " + gdbserverSocket);
new File(gdbserverSocket).delete();
}
if (usePing) {
debugLog("removing ping file " + pingFile);
File ping = new File(pingFile);
if (ping.exists()) {
if (!ping.delete())
debugLog("ping file cannot be deleted");
if (gdbserverSocket != null) {
debugLog("removing gdb socket " + gdbserverSocket);
new File(gdbserverSocket).delete();
}
}
if (usePong) {
debugLog("removing pong file " + pongFile);
File pong = new File(pongFile);
if (pong.exists()) {
if (!pong.delete())
debugLog("pong file cannot be deleted");
}
}
debugLog("starting " + gdbserverCommand);
m_debuggerProcess = Runtime.getRuntime().exec(gdbserverCommand);
debugLog("gdbserver started");
if (useSocket) {
int i;
for (i = 0; i < maxAttempts; ++i) {
debugLog("waiting for socket at " + gdbserverSocket + ", attempt " + i);
File file = new File(gdbserverSocket);
if (file.exists()) {
file.setReadable(true, false);
file.setWritable(true, false);
file.setExecutable(true, false);
break;
if (usePing) {
debugLog("removing ping file " + pingFile);
File ping = new File(pingFile);
if (ping.exists()) {
if (!ping.delete())
debugLog("ping file cannot be deleted");
}
Thread.sleep(napTime);
}
if (i == maxAttempts) {
debugLog("time out when waiting for debug socket");
return false;
if (usePong) {
debugLog("removing pong file " + pongFile);
File pong = new File(pongFile);
if (pong.exists()) {
if (!pong.delete())
debugLog("pong file cannot be deleted");
}
}
debugLog("socket ok");
} else {
debugLog("socket not used");
}
debugLog("starting " + gdbserverCommand);
m_debuggerProcess = Runtime.getRuntime().exec(gdbserverCommand);
debugLog("gdbserver started");
if (usePingSocket) {
DebugWaitRunnable runnable = new DebugWaitRunnable(pingSocket);
Thread waitThread = new Thread(runnable);
waitThread.start();
if (useSocket) {
int i;
for (i = 0; i < maxAttempts; ++i) {
debugLog("waiting for socket at " + gdbserverSocket + ", attempt " + i);
File file = new File(gdbserverSocket);
if (file.exists()) {
file.setReadable(true, false);
file.setWritable(true, false);
file.setExecutable(true, false);
break;
}
Thread.sleep(napTime);
}
int i;
for (i = 0; i < maxAttempts && waitThread.isAlive(); ++i) {
debugLog("Waiting for debug socket connect");
debugLog("go to sleep");
Thread.sleep(napTime);
}
if (i == maxAttempts) {
debugLog("time out when waiting for debug socket");
return false;
}
if (i == maxAttempts) {
debugLog("time out when waiting for ping socket");
runnable.shutdown();
return false;
}
if (runnable.wasFailure) {
debugLog("Could not connect to debug client");
return false;
debugLog("socket ok");
} else {
debugLog("Got pid acknowledgment");
debugLog("socket not used");
}
}
if (usePing) {
// Tell we are ready.
debugLog("writing ping at " + pingFile);
FileWriter writer = new FileWriter(pingFile);
writer.write("" + android.os.Process.myPid());
writer.close();
File file = new File(pingFile);
file.setReadable(true, false);
file.setWritable(true, false);
file.setExecutable(true, false);
debugLog("wrote ping");
} else {
debugLog("ping not requested");
}
if (usePingSocket) {
DebugWaitRunnable runnable = new DebugWaitRunnable(pingSocket);
Thread waitThread = new Thread(runnable);
waitThread.start();
// Wait until other side is ready.
if (usePong) {
int i;
for (i = 0; i < maxAttempts; ++i) {
debugLog("waiting for pong at " + pongFile + ", attempt " + i);
File file = new File(pongFile);
if (file.exists()) {
file.delete();
break;
int i;
for (i = 0; i < maxAttempts && waitThread.isAlive(); ++i) {
debugLog("Waiting for debug socket connect");
debugLog("go to sleep");
Thread.sleep(napTime);
}
debugLog("go to sleep");
Thread.sleep(napTime);
}
debugLog("Removing pingFile " + pingFile);
new File(pingFile).delete();
if (i == maxAttempts) {
debugLog("time out when waiting for pong file");
return false;
if (i == maxAttempts) {
debugLog("time out when waiting for ping socket");
runnable.shutdown();
return false;
}
if (runnable.wasFailure) {
debugLog("Could not connect to debug client");
return false;
} else {
debugLog("Got pid acknowledgment");
}
}
debugLog("got pong " + pongFile);
} else {
debugLog("pong not requested");
if (usePing) {
// Tell we are ready.
debugLog("writing ping at " + pingFile);
FileWriter writer = new FileWriter(pingFile);
writer.write("" + android.os.Process.myPid());
writer.close();
File file = new File(pingFile);
file.setReadable(true, false);
file.setWritable(true, false);
file.setExecutable(true, false);
debugLog("wrote ping");
} else {
debugLog("ping not requested");
}
// Wait until other side is ready.
if (usePong) {
int i;
for (i = 0; i < maxAttempts; ++i) {
debugLog("waiting for pong at " + pongFile + ", attempt " + i);
File file = new File(pongFile);
if (file.exists()) {
file.delete();
break;
}
debugLog("go to sleep");
Thread.sleep(napTime);
}
debugLog("Removing pingFile " + pingFile);
new File(pingFile).delete();
if (i == maxAttempts) {
debugLog("time out when waiting for pong file");
return false;
}
debugLog("got pong " + pongFile);
} else {
debugLog("pong not requested");
}
} catch (IOException ioe) {
ioe.printStackTrace();
} catch (SecurityException se) {
se.printStackTrace();
}
} catch (IOException ioe) {
ioe.printStackTrace();
} catch (SecurityException se) {
se.printStackTrace();
}
}
if (/*(ai.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0
&&*/ extras.containsKey("qml_debug")
&& extras.getString("qml_debug").equals("true")) {
String qmljsdebugger;
if (extras.containsKey("qmljsdebugger")) {
qmljsdebugger = extras.getString("qmljsdebugger");
qmljsdebugger.replaceAll("\\s", ""); // remove whitespace for security
} else {
qmljsdebugger = "port:3768";
if (/*(ai.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0
&&*/ extras.containsKey("qml_debug")
&& extras.getString("qml_debug").equals("true")) {
String qmljsdebugger;
if (extras.containsKey("qmljsdebugger")) {
qmljsdebugger = extras.getString("qmljsdebugger");
qmljsdebugger.replaceAll("\\s", ""); // remove whitespace for security
} else {
qmljsdebugger = "port:3768";
}
m_applicationParameters += "\t-qmljsdebugger=" + qmljsdebugger;
}
m_applicationParameters += "\t-qmljsdebugger=" + qmljsdebugger;
}
if (extras.containsKey("extraenvvars")) {
try {
m_environmentVariables += "\t" + new String(Base64.decode(extras.getString("extraenvvars"), Base64.DEFAULT), "UTF-8");
} catch (Exception e) {
e.printStackTrace();
if (extras.containsKey("extraenvvars")) {
try {
m_environmentVariables += "\t" + new String(Base64.decode(extras.getString("extraenvvars"), Base64.DEFAULT), "UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
}
}
if (extras.containsKey("extraappparams")) {
try {
m_applicationParameters += "\t" + new String(Base64.decode(extras.getString("extraappparams"), Base64.DEFAULT), "UTF-8");
} catch (Exception e) {
e.printStackTrace();
if (extras.containsKey("extraappparams")) {
try {
m_applicationParameters += "\t" + new String(Base64.decode(extras.getString("extraappparams"), Base64.DEFAULT), "UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (Exception e) {
// This is not an error, so keep it silent
// e.printStackTrace();
}
} // extras != null

View File

@ -137,6 +137,9 @@ function(QT5_CREATE_MOC_COMMAND infile outfile moc_flags moc_options moc_target
DEPENDS ${infile} ${moc_depends}
${_moc_working_dir}
VERBATIM)
set_source_files_properties(${infile} PROPERTIES SKIP_AUTOMOC ON)
set_source_files_properties(${outfile} PROPERTIES SKIP_AUTOMOC ON)
set_source_files_properties(${outfile} PROPERTIES SKIP_AUTOUIC ON)
endfunction()
@ -155,7 +158,6 @@ function(QT5_GENERATE_MOC infile outfile )
set(moc_target ${ARGV3})
endif()
qt5_create_moc_command(${abs_infile} ${_outfile} "${moc_flags}" "" "${moc_target}" "")
set_source_files_properties(${outfile} PROPERTIES SKIP_AUTOMOC TRUE) # dont run automoc on this file
endfunction()
@ -246,6 +248,7 @@ function(QT5_ADD_BINARY_RESOURCES target )
get_filename_component(infile ${it} ABSOLUTE)
_QT5_PARSE_QRC_FILE(${infile} _out_depends _rc_depends)
set_source_files_properties(${infile} PROPERTIES SKIP_AUTORCC ON)
set(infiles ${infiles} ${infile})
set(out_depends ${out_depends} ${_out_depends})
set(rc_depends ${rc_depends} ${_rc_depends})
@ -255,7 +258,6 @@ function(QT5_ADD_BINARY_RESOURCES target )
COMMAND ${Qt5Core_RCC_EXECUTABLE}
ARGS ${rcc_options} --binary --name ${target} --output ${rcc_destination} ${infiles}
DEPENDS ${rc_depends} ${out_depends} VERBATIM)
add_custom_target(${target} ALL DEPENDS ${rcc_destination})
endfunction()
@ -283,12 +285,15 @@ function(QT5_ADD_RESOURCES outfiles )
set(outfile ${CMAKE_CURRENT_BINARY_DIR}/qrc_${outfilename}.cpp)
_QT5_PARSE_QRC_FILE(${infile} _out_depends _rc_depends)
set_source_files_properties(${infile} PROPERTIES SKIP_AUTORCC ON)
add_custom_command(OUTPUT ${outfile}
COMMAND ${Qt5Core_RCC_EXECUTABLE}
ARGS ${rcc_options} --name ${outfilename} --output ${outfile} ${infile}
MAIN_DEPENDENCY ${infile}
DEPENDS ${_rc_depends} "${out_depends}" VERBATIM)
set_source_files_properties(${outfile} PROPERTIES SKIP_AUTOMOC ON)
set_source_files_properties(${outfile} PROPERTIES SKIP_AUTOUIC ON)
list(APPEND ${outfiles} ${outfile})
endforeach()
set(${outfiles} ${${outfiles}} PARENT_SCOPE)

View File

@ -150,7 +150,7 @@ public:
Q_DECL_CONSTEXPR inline bool testFlag(Enum f) const Q_DECL_NOTHROW { return (i & Int(f)) == Int(f) && (Int(f) != 0 || i == Int(f) ); }
Q_DECL_RELAXED_CONSTEXPR inline QFlags &setFlag(Enum f, bool on = true) Q_DECL_NOTHROW
{
return on ? (*this |= f) : (*this &= ~f);
return on ? (*this |= f) : (*this &= ~Int(f));
}
private:

View File

@ -44,7 +44,16 @@
#include <QtCore/qmetatype.h>
#include <string.h>
#if defined __F16C__
#if defined(QT_COMPILER_SUPPORTS_F16C) && defined(__AVX2__) && !defined(__F16C__)
// All processors that support AVX2 do support F16C too. That doesn't mean
// we're allowed to use the intrinsics directly, so we'll do it only for
// the Intel and Microsoft's compilers.
# if defined(Q_CC_INTEL) || defined(Q_CC_MSVC)
# define __F16C__ 1
# endif
#endif
#if defined(QT_COMPILER_SUPPORTS_F16C) && defined(__F16C__)
#include <immintrin.h>
#endif
@ -119,7 +128,7 @@ QT_WARNING_DISABLE_CLANG("-Wc99-extensions")
QT_WARNING_DISABLE_GCC("-Wold-style-cast")
inline qfloat16::qfloat16(float f) Q_DECL_NOTHROW
{
#if defined(QT_COMPILER_SUPPORTS_F16C) && (defined(__F16C__) || defined(__AVX2__))
#if defined(QT_COMPILER_SUPPORTS_F16C) && defined(__F16C__)
__m128 packsingle = _mm_set_ss(f);
__m128i packhalf = _mm_cvtps_ph(packsingle, 0);
b16 = _mm_extract_epi16(packhalf, 0);
@ -137,7 +146,7 @@ QT_WARNING_POP
inline qfloat16::operator float() const Q_DECL_NOTHROW
{
#if defined(QT_COMPILER_SUPPORTS_F16C) && (defined(__F16C__) || defined(__AVX2__))
#if defined(QT_COMPILER_SUPPORTS_F16C) && defined(__F16C__)
__m128i packhalf = _mm_cvtsi32_si128(b16);
__m128 packsingle = _mm_cvtph_ps(packhalf);
return _mm_cvtss_f32(packsingle);

View File

@ -1879,7 +1879,7 @@ QByteArray QIODevice::peek(qint64 maxSize)
}
/*!
\since 5.11
\since 5.10
Skips up to \a maxSize bytes from the device. Returns the number of bytes
actually skipped, or -1 on error.

View File

@ -255,6 +255,7 @@ void QLoggingSettingsParser::parseNextLine(QStringRef line)
QLoggingRegistry::QLoggingRegistry()
: categoryFilter(defaultCategoryFilter)
{
initalizeRules(); // Init on first use
}
static bool qtLoggingDebug()
@ -283,7 +284,7 @@ static QVector<QLoggingRule> loadRulesFromFile(const QString &filePath)
Initializes the rules database by loading
$QT_LOGGING_CONF, $QT_LOGGING_RULES, and .config/QtProject/qtlogging.ini.
*/
void QLoggingRegistry::init()
void QLoggingRegistry::initalizeRules()
{
QVector<QLoggingRule> er, qr, cr;
// get rules from environment

View File

@ -113,7 +113,7 @@ class Q_AUTOTEST_EXPORT QLoggingRegistry
public:
QLoggingRegistry();
void init();
void initalizeRules();
void registerCategory(QLoggingCategory *category, QtMsgType enableForLevel);
void unregisterCategory(QLoggingCategory *category);

View File

@ -201,6 +201,10 @@ QString QStandardPaths::writableLocation(StandardLocation type)
return result;
}
#ifndef QT_BOOTSTRAPPED
extern QString qAppFileName();
#endif
QStringList QStandardPaths::standardLocations(StandardLocation type)
{
QStringList dirs;
@ -217,8 +221,13 @@ QStringList QStandardPaths::standardLocations(StandardLocation type)
dirs.append(programData);
}
#ifndef QT_BOOTSTRAPPED
dirs.append(QCoreApplication::applicationDirPath());
const QString dataDir = QCoreApplication::applicationDirPath() + QLatin1String("/data");
// Note: QCoreApplication::applicationDirPath(), while static, requires
// an application instance. But we might need to resolve the standard
// locations earlier than that, so we fall back to qAppFileName().
QString applicationDirPath = qApp ? QCoreApplication::applicationDirPath()
: QFileInfo(qAppFileName()).path();
dirs.append(applicationDirPath);
const QString dataDir = applicationDirPath + QLatin1String("/data");
dirs.append(dataDir);
if (!isGenericConfigLocation(type)) {

View File

@ -802,8 +802,6 @@ void QCoreApplicationPrivate::init()
if (!coreappdata()->applicationVersionSet)
coreappdata()->applicationVersion = appVersion();
QLoggingRegistry::instance()->init();
#if QT_CONFIG(library)
// Reset the lib paths, so that they will be recomputed, taking the availability of argv[0]
// into account. If necessary, recompute right away and replay the manual changes on top of the

View File

@ -414,13 +414,18 @@ bool QSemaphore::tryAcquire(int n)
bool QSemaphore::tryAcquire(int n, int timeout)
{
Q_ASSERT_X(n >= 0, "QSemaphore::tryAcquire", "parameter 'n' must be non-negative");
// We're documented to accept any negative value as "forever"
// but QDeadlineTimer only accepts -1.
timeout = qMax(timeout, -1);
if (futexAvailable())
return futexSemaphoreTryAcquire<true>(u, n, timeout < 0 ? -1 : timeout);
return futexSemaphoreTryAcquire<true>(u, n, timeout);
QDeadlineTimer timer(timeout);
QMutexLocker locker(&d->mutex);
qint64 remainingTime = timer.remainingTime();
while (n > d->avail && remainingTime > 0) {
while (n > d->avail && remainingTime != 0) {
if (!d->cond.wait(locker.mutex(), remainingTime))
return false;
remainingTime = timer.remainingTime();

View File

@ -3809,17 +3809,18 @@ QString QLocale::toCurrencyString(double value, const QString &symbol, int preci
/*!
\since 5.10
Converts a size in bytes to a human-readable localized string, expressed in
a unit for which the numeric portion is at least 1 but as low as
possible. For example if \a bytes is 16384, \a precision is 2, and \a format
is \c DataSizeIecFormat (the default), this function returns "16.00 KiB";
for 1330409069609 bytes it returns "1.21 GiB"; and so on. If \a format is \c
DataSizeIecFormat or \c DataSizeTraditionalFormat, the given number of bytes
is divided by a power of 1024, with result less than 1024; for \c
DataSizeSIFormat, it is divided by a power of 1000, with result less than
1000. DataSizeIecFormat uses the new IEC standard quantifiers Ki, Mi and so
on, whereas DataSizeSIFormat uses and DataSizeTraditionalFormat abuses the
older SI quantifiers k, M, etc.
Converts a size in bytes to a human-readable localized string, comprising a
number and a quantified unit. The quantifier is chosen such that the number
is at least one, and as small as possible. For example if \a bytes is
16384, \a precision is 2, and \a format is \l DataSizeIecFormat (the
default), this function returns "16.00 KiB"; for 1330409069609 bytes it
returns "1.21 GiB"; and so on. If \a format is \l DataSizeIecFormat or
\l DataSizeTraditionalFormat, the given number of bytes is divided by a
power of 1024, with result less than 1024; for \l DataSizeSIFormat, it is
divided by a power of 1000, with result less than 1000.
\c DataSizeIecFormat uses the new IEC standard quantifiers Ki, Mi and so on,
whereas \c DataSizeSIFormat uses the older SI quantifiers k, M, etc., and
\c DataSizeTraditionalFormat abuses them.
*/
QString QLocale::formattedDataSize(qint64 bytes, int precision, DataSizeFormats format)
{

View File

@ -652,32 +652,6 @@ Q_CORE_EXPORT QBasicAtomicInteger<unsigned> qt_cpu_features[2] = { Q_BASIC_ATOMI
void qDetectCpuFeatures()
{
#if defined(Q_CC_GNU) && !defined(Q_CC_CLANG) && !defined(Q_CC_INTEL)
# if Q_CC_GNU < 403
// GCC 4.2 (at least the one that comes with Apple's XCode, on Mac) is
// known to be broken beyond repair in dealing with the inline assembly
// above. It will generate bad code that could corrupt important registers
// like the PIC register. The behaviour of code after this function would
// be totally unpredictable.
//
// For that reason, simply forego the CPUID check at all and return the set
// of features that we found at compile time, through the #defines from the
// compiler. This should at least allow code to execute, even if none of
// the specialized code found in Qt GUI and elsewhere will ever be enabled
// (it's the user's fault for using a broken compiler).
//
// This also disables the runtime checking that the processor actually
// contains all the features that the code required. Qt 4 ran for years
// like that, so it shouldn't be a problem.
qt_cpu_features[0].store(minFeature | quint32(QSimdInitialized));
#ifndef Q_ATOMIC_INT64_IS_SUPPORTED
qt_cpu_features[1].store(minFeature >> 32);
#endif
return;
# endif
#endif
quint64 f = detectProcessorFeatures();
QByteArray disable = qgetenv("QT_NO_CPU_FEATURE");
if (!disable.isEmpty()) {

View File

@ -1050,7 +1050,18 @@ QByteArray QTzTimeZonePrivate::systemTimeZoneId() const
if (ianaId == "/etc/localtime")
ianaId.clear();
// On Debian Etch and later /etc/localtime is real file with name held in /etc/timezone
// On most distros /etc/localtime is a symlink to a real file so extract name from the path
if (ianaId.isEmpty()) {
const QString path = QFile::symLinkTarget(QStringLiteral("/etc/localtime"));
if (!path.isEmpty()) {
// /etc/localtime is a symlink to the current TZ file, so extract from path
int index = path.indexOf(QLatin1String("/zoneinfo/"));
if (index != -1)
ianaId = path.mid(index + 10).toUtf8();
}
}
// On Debian Etch up to Jessie, /etc/localtime is a regular file while the actual name is in /etc/timezone
if (ianaId.isEmpty()) {
QFile tzif(QStringLiteral("/etc/timezone"));
if (tzif.open(QIODevice::ReadOnly)) {
@ -1061,16 +1072,6 @@ QByteArray QTzTimeZonePrivate::systemTimeZoneId() const
}
}
// On other distros /etc/localtime is symlink to real file so can extract name from the path
if (ianaId.isEmpty()) {
const QString path = QFile::symLinkTarget(QStringLiteral("/etc/localtime"));
if (!path.isEmpty()) {
// /etc/localtime is a symlink to the current TZ file, so extract from path
int index = path.indexOf(QLatin1String("/zoneinfo/")) + 10;
ianaId = path.mid(index).toUtf8();
}
}
// On some Red Hat distros /etc/localtime is real file with name held in /etc/sysconfig/clock
// in a line like ZONE="Europe/Oslo" or TIMEZONE="Europe/Oslo"
if (ianaId.isEmpty()) {

View File

@ -215,7 +215,7 @@ public:
const uchar *constBits() const;
#if QT_DEPRECATED_SINCE(5, 10)
QT_DEPRECATED int byteCount() const;
QT_DEPRECATED_X("Use sizeInBytes") int byteCount() const;
#endif
qssize_t sizeInBytes() const;

View File

@ -58,6 +58,9 @@ QT_BEGIN_NAMESPACE
*/
QPlatformPixmap *QPlatformPixmap::create(int w, int h, PixelType type)
{
if (Q_UNLIKELY(!QGuiApplicationPrivate::platformIntegration()))
qFatal("QPlatformPixmap: QGuiApplication required");
QPlatformPixmap *data = QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(static_cast<QPlatformPixmap::PixelType>(type));
data->resize(w, h);
return data;

View File

@ -265,12 +265,12 @@ void QWindowSystemInterface::handleWindowScreenChanged(QWindow *window, QScreen
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
void QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationState newState, bool forcePropagate)
QT_DEFINE_QPA_EVENT_HANDLER(void, handleApplicationStateChanged, Qt::ApplicationState newState, bool forcePropagate)
{
Q_ASSERT(QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ApplicationState));
QWindowSystemInterfacePrivate::ApplicationStateChangedEvent *e =
new QWindowSystemInterfacePrivate::ApplicationStateChangedEvent(newState, forcePropagate);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(e);
}
QWindowSystemInterfacePrivate::GeometryChangeEvent::GeometryChangeEvent(QWindow *window, const QRect &newGeometry)

View File

@ -207,6 +207,7 @@ public:
static void handleWindowStateChanged(QWindow *window, Qt::WindowStates newState, int oldState = -1);
static void handleWindowScreenChanged(QWindow *window, QScreen *newScreen);
template<typename Delivery = QWindowSystemInterface::DefaultDelivery>
static void handleApplicationStateChanged(Qt::ApplicationState newState, bool forcePropagate = false);
#ifndef QT_NO_DRAGANDDROP

View File

@ -1231,20 +1231,20 @@ void QHttpNetworkConnectionPrivate::_q_hostLookupFinished(const QHostInfo &info)
if (dequeueRequest(channels[0].socket)) {
emitReplyError(channels[0].socket, channels[0].reply, QNetworkReply::HostNotFoundError);
networkLayerState = QHttpNetworkConnectionPrivate::Unknown;
}
#ifndef QT_NO_SSL
else if (connectionType == QHttpNetworkConnection::ConnectionTypeSPDY) {
} else if (connectionType == QHttpNetworkConnection::ConnectionTypeSPDY
|| connectionType == QHttpNetworkConnection::ConnectionTypeHTTP2) {
for (const HttpMessagePair &spdyPair : qAsConst(channels[0].spdyRequestsToSend)) {
// emit error for all replies
QHttpNetworkReply *currentReply = spdyPair.second;
Q_ASSERT(currentReply);
emitReplyError(channels[0].socket, currentReply, QNetworkReply::HostNotFoundError);
}
}
#endif // QT_NO_SSL
else {
// Should not happen
qWarning("QHttpNetworkConnectionPrivate::_q_hostLookupFinished could not de-queue request");
} else {
// Should not happen: we start a host lookup before sending a request,
// so it's natural to have requests either in SPDY/HTTP/2 queue,
// or in low/high priority queues.
qWarning("QHttpNetworkConnectionPrivate::_q_hostLookupFinished"
" could not de-queue request, failed to report HostNotFoundError");
networkLayerState = QHttpNetworkConnectionPrivate::Unknown;
}
}

View File

@ -1031,8 +1031,7 @@ QNetworkConfiguration QNetworkAccessManager::configuration() const
if (session) {
return session->configuration();
} else {
QNetworkConfigurationManager manager;
return manager.defaultConfiguration();
return d->networkConfigurationManager.defaultConfiguration();
}
}
@ -1056,12 +1055,11 @@ QNetworkConfiguration QNetworkAccessManager::activeConfiguration() const
Q_D(const QNetworkAccessManager);
QSharedPointer<QNetworkSession> networkSession(d->getNetworkSession());
QNetworkConfigurationManager manager;
if (networkSession) {
return manager.configurationFromIdentifier(
return d->networkConfigurationManager.configurationFromIdentifier(
networkSession->sessionProperty(QLatin1String("ActiveConfiguration")).toString());
} else {
return manager.defaultConfiguration();
return d->networkConfigurationManager.defaultConfiguration();
}
}
@ -1390,17 +1388,16 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera
}
if (!d->networkSessionStrongRef && (d->initializeSession || !d->networkConfiguration.identifier().isEmpty())) {
QNetworkConfigurationManager manager;
if (!d->networkConfiguration.identifier().isEmpty()) {
if ((d->networkConfiguration.state() & QNetworkConfiguration::Defined)
&& d->networkConfiguration != manager.defaultConfiguration())
d->createSession(manager.defaultConfiguration());
&& d->networkConfiguration != d->networkConfigurationManager.defaultConfiguration())
d->createSession(d->networkConfigurationManager.defaultConfiguration());
else
d->createSession(d->networkConfiguration);
} else {
if (manager.capabilities() & QNetworkConfigurationManager::NetworkSessionRequired)
d->createSession(manager.defaultConfiguration());
if (d->networkSessionRequired)
d->createSession(d->networkConfigurationManager.defaultConfiguration());
else
d->initializeSession = false;
}
@ -1932,8 +1929,8 @@ void QNetworkAccessManagerPrivate::_q_onlineStateChanged(bool isOnline)
online = (networkConfiguration.state() & QNetworkConfiguration::Active);
} else {
if (online != isOnline) {
_q_networkSessionClosed();
createSession(q->configuration());
_q_networkSessionClosed();
createSession(q->configuration());
online = isOnline;
}
}
@ -1957,13 +1954,13 @@ void QNetworkAccessManagerPrivate::_q_configurationChanged(const QNetworkConfigu
const QString id = configuration.identifier();
if (configuration.state().testFlag(QNetworkConfiguration::Active)) {
if (!onlineConfigurations.contains(id)) {
QSharedPointer<QNetworkSession> session(getNetworkSession());
if (session) {
if (online && session->configuration().identifier()
!= networkConfigurationManager.defaultConfiguration().identifier()) {
onlineConfigurations.insert(id);
// CHECK: If it's having Active flag - why would it be disconnected ???
//this one disconnected but another one is online,
// close and create new session
_q_networkSessionClosed();
@ -1974,6 +1971,7 @@ void QNetworkAccessManagerPrivate::_q_configurationChanged(const QNetworkConfigu
} else if (onlineConfigurations.contains(id)) {
//this one is disconnecting
// CHECK: If it disconnected while we create a session over a down configuration ???
onlineConfigurations.remove(id);
if (!onlineConfigurations.isEmpty()) {
_q_networkSessionClosed();

View File

@ -1215,10 +1215,8 @@ qint64 QNativeSocketEnginePrivate::nativeReceiveDatagram(char *data, qint64 maxL
msg.dwBufferCount = 1;
msg.name = reinterpret_cast<LPSOCKADDR>(&aa);
msg.namelen = sizeof(aa);
if (options & (QAbstractSocketEngine::WantDatagramHopLimit | QAbstractSocketEngine::WantDatagramDestination)) {
msg.Control.buf = cbuf;
msg.Control.len = sizeof(cbuf);
}
msg.Control.buf = cbuf;
msg.Control.len = sizeof(cbuf);
DWORD flags = 0;
DWORD bytesRead = 0;

View File

@ -112,9 +112,11 @@ static bool isDBusTrayAvailable() {
#ifndef QT_NO_DBUS
static bool checkDBusGlobalMenuAvailable()
{
QDBusConnection connection = QDBusConnection::sessionBus();
QString registrarService = QStringLiteral("com.canonical.AppMenu.Registrar");
return connection.interface()->isServiceRegistered(registrarService);
const QDBusConnection connection = QDBusConnection::sessionBus();
static const QString registrarService = QStringLiteral("com.canonical.AppMenu.Registrar");
if (const auto iface = connection.interface())
return iface->isServiceRegistered(registrarService);
return false;
}
static bool isDBusGlobalMenuAvailable()

View File

@ -47,7 +47,6 @@ namespace QtAndroidClipboard
{
QAndroidPlatformClipboard *m_manager = nullptr;
static char const *const QtNativeClassName = "org/qtproject/qt5/android/QtNative";
static JNINativeMethod methods[] = {
{"onClipboardDataChanged", "()V", (void *)onClipboardDataChanged}
};

View File

@ -354,6 +354,12 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
m_platformWindow->handleExposeEvent(QRectF::fromCGRect(self.bounds).toRect());
}
- (void)viewDidChangeBackingProperties
{
if (self.layer)
self.layer.contentsScale = self.window.backingScaleFactor;
}
- (BOOL)isFlipped
{
return YES;

View File

@ -39,6 +39,8 @@
#include "qiosapplicationstate.h"
#include "qiosglobal.h"
#include <qpa/qwindowsysteminterface.h>
#include <QtCore/qcoreapplication.h>
@ -72,8 +74,8 @@ static Qt::ApplicationState qtApplicationState(UIApplicationState uiApplicationS
static void handleApplicationStateChanged(UIApplicationState uiApplicationState)
{
Qt::ApplicationState state = qtApplicationState(uiApplicationState);
QWindowSystemInterface::handleApplicationStateChanged(state);
QWindowSystemInterface::flushWindowSystemEvents();
qCDebug(lcQpaApplication) << "moved to" << state;
QWindowSystemInterface::handleApplicationStateChanged<QWindowSystemInterface::SynchronousDelivery>(state);
}
QT_BEGIN_NAMESPACE

View File

@ -165,8 +165,6 @@ bool QIOSContext::makeCurrent(QPlatformSurface *surface)
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
framebufferObject.depthRenderbuffer);
}
connect(static_cast<QIOSWindow *>(surface), SIGNAL(destroyed(QObject*)), this, SLOT(windowDestroyed(QObject*)));
} else {
glBindFramebuffer(GL_FRAMEBUFFER, framebufferObject.handle);
}
@ -249,8 +247,13 @@ QIOSContext::FramebufferObject &QIOSContext::backingFramebufferObjectFor(QPlatfo
// should probably use QOpenGLMultiGroupSharedResource to track the shared default-FBOs.
if (m_sharedContext)
return m_sharedContext->backingFramebufferObjectFor(surface);
else
return m_framebufferObjects[surface];
if (!m_framebufferObjects.contains(surface)) {
// We're about to create a new FBO, make sure it's cleaned up as well
connect(static_cast<QIOSWindow *>(surface), SIGNAL(destroyed(QObject*)), this, SLOT(windowDestroyed(QObject*)));
}
return m_framebufferObjects[surface];
}
GLuint QIOSContext::defaultFramebufferObject(QPlatformSurface *surface) const

View File

@ -47,7 +47,9 @@
QT_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(lcQpaApplication);
Q_DECLARE_LOGGING_CATEGORY(lcQpaInputMethods);
Q_DECLARE_LOGGING_CATEGORY(lcQpaWindow);
#if !defined(QT_NO_DEBUG)
#define qImDebug \

View File

@ -44,7 +44,9 @@
QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(lcQpaApplication, "qt.qpa.application");
Q_LOGGING_CATEGORY(lcQpaInputMethods, "qt.qpa.input.methods");
Q_LOGGING_CATEGORY(lcQpaWindow, "qt.qpa.window");
bool isQtApplication()
{

View File

@ -58,8 +58,6 @@ class QIOSServices;
class QIOSIntegration : public QPlatformNativeInterface, public QPlatformIntegration
{
Q_OBJECT
Q_PROPERTY(bool debugWindowManagement READ debugWindowManagement WRITE setDebugWindowManagement);
public:
QIOSIntegration();
~QIOSIntegration();
@ -104,9 +102,6 @@ public:
void *nativeResourceForWindow(const QByteArray &resource, QWindow *window) override;
void setDebugWindowManagement(bool);
bool debugWindowManagement() const;
QFactoryLoader *optionalPlugins() { return m_optionalPlugins; }
private:
@ -123,8 +118,6 @@ private:
#ifndef Q_OS_TVOS
QIOSTextInputOverlay m_textInputOverlay;
#endif
bool m_debugWindowManagement;
};
QT_END_NAMESPACE

View File

@ -85,7 +85,6 @@ QIOSIntegration::QIOSIntegration()
, m_platformServices(new QIOSServices)
, m_accessibility(0)
, m_optionalPlugins(new QFactoryLoader(QIosOptionalPluginInterface_iid, QLatin1String("/platforms/darwin")))
, m_debugWindowManagement(false)
{
if (Q_UNLIKELY(![UIApplication sharedApplication])) {
qFatal("Error: You are creating QApplication before calling UIApplicationMain.\n" \
@ -94,10 +93,6 @@ QIOSIntegration::QIOSIntegration()
"'applicationDidFinishLaunching' inside your UIApplication delegate.\n");
}
// The backingstore needs a global share context in order to support composition in
// QPlatformBackingStore.
qApp->setAttribute(Qt::AA_ShareOpenGLContexts, true);
// Set current directory to app bundle folder
QDir::setCurrent(QString::fromUtf8([[[NSBundle mainBundle] bundlePath] UTF8String]));
@ -325,16 +320,6 @@ void *QIOSIntegration::nativeResourceForWindow(const QByteArray &resource, QWind
return 0;
}
void QIOSIntegration::setDebugWindowManagement(bool enabled)
{
m_debugWindowManagement = enabled;
}
bool QIOSIntegration::debugWindowManagement() const
{
return m_debugWindowManagement;
}
// ---------------------------------------------------------
#include "moc_qiosintegration.cpp"

View File

@ -77,8 +77,7 @@
if (!(self = [super init]))
return nil;
QIOSIntegration *iosIntegration = QIOSIntegration::instance();
if (iosIntegration && iosIntegration->debugWindowManagement()) {
if (qEnvironmentVariableIntValue("QT_IOS_DEBUG_WINDOW_MANAGEMENT")) {
static UIImage *gridPattern = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{

View File

@ -239,15 +239,28 @@ void QIOSWindow::setWindowState(Qt::WindowStates state)
if (window()->isTopLevel() && window()->isVisible() && window()->isActive())
[m_view.qtViewController updateProperties];
if (state & Qt::WindowMinimized)
if (state & Qt::WindowMinimized) {
applyGeometry(QRect());
else if (state & Qt::WindowFullScreen)
applyGeometry(screen()->geometry());
else if (state & Qt::WindowMaximized)
applyGeometry(window()->flags() & Qt::MaximizeUsingFullscreenGeometryHint ?
screen()->geometry() : screen()->availableGeometry());
else
} else if (state & (Qt::WindowFullScreen | Qt::WindowMaximized)) {
// When an application is in split-view mode, the UIScreen still has the
// same geometry, but the UIWindow is resized to the area reserved for the
// application. We use this to constrain the geometry used when applying the
// fullscreen or maximized window states. Note that we do not do this
// in applyGeometry(), as we don't want to artificially limit window
// placement "outside" of the screen bounds if that's what the user wants.
QRect uiWindowBounds = QRectF::fromCGRect(m_view.window.bounds).toRect();
QRect fullscreenGeometry = screen()->geometry().intersected(uiWindowBounds);
QRect maximizedGeometry = window()->flags() & Qt::MaximizeUsingFullscreenGeometryHint ?
fullscreenGeometry : screen()->availableGeometry().intersected(uiWindowBounds);
if (state & Qt::WindowFullScreen)
applyGeometry(fullscreenGeometry);
else
applyGeometry(maximizedGeometry);
} else {
applyGeometry(m_normalGeometry);
}
}
void QIOSWindow::setParent(const QPlatformWindow *parentWindow)

View File

@ -88,7 +88,7 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
self.multipleTouchEnabled = YES;
#endif
if (QIOSIntegration::instance()->debugWindowManagement()) {
if (qEnvironmentVariableIntValue("QT_IOS_DEBUG_WINDOW_MANAGEMENT")) {
static CGFloat hue = 0.0;
CGFloat lastHue = hue;
for (CGFloat diff = 0; diff < 0.1 || diff > 0.9; diff = fabs(hue - lastHue))
@ -97,7 +97,6 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
#define colorWithBrightness(br) \
[UIColor colorWithHue:hue saturation:0.5 brightness:br alpha:1.0].CGColor
self.layer.backgroundColor = colorWithBrightness(0.5);
self.layer.borderColor = colorWithBrightness(1.0);
self.layer.borderWidth = 1.0;
}
@ -163,6 +162,7 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
QWindow *window = m_qioswindow->window();
QRect lastReportedGeometry = qt_window_private(window)->geometry;
QRect currentGeometry = QRectF::fromCGRect(self.frame).toRect();
qCDebug(lcQpaWindow) << m_qioswindow->window() << "new geometry is" << currentGeometry;
QWindowSystemInterface::handleGeometryChange<QWindowSystemInterface::SynchronousDelivery>(window, currentGeometry);
if (currentGeometry.size() != lastReportedGeometry.size()) {
@ -195,6 +195,7 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
region = QRect(QPoint(), bounds);
}
qCDebug(lcQpaWindow) << m_qioswindow->window() << region << "isExposed" << m_qioswindow->isExposed();
QWindowSystemInterface::handleExposeEvent<QWindowSystemInterface::SynchronousDelivery>(m_qioswindow->window(), region);
}

View File

@ -59,6 +59,9 @@ function(QT5_WRAP_UI outfiles )
COMMAND ${Qt5Widgets_UIC_EXECUTABLE}
ARGS ${ui_options} -o ${outfile} ${infile}
MAIN_DEPENDENCY ${infile} VERBATIM)
set_source_files_properties(${infile} PROPERTIES SKIP_AUTOUIC ON)
set_source_files_properties(${outfile} PROPERTIES SKIP_AUTOMOC ON)
set_source_files_properties(${outfile} PROPERTIES SKIP_AUTOUIC ON)
list(APPEND ${outfiles} ${outfile})
endforeach()
set(${outfiles} ${${outfiles}} PARENT_SCOPE)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View File

@ -2086,40 +2086,26 @@ void QHeaderViewPrivate::_q_layoutChanged()
{
Q_Q(QHeaderView);
viewport->update();
if (persistentHiddenSections.isEmpty() || modelIsEmpty()) {
if (modelSectionCount() != sectionCount())
q->initializeSections();
persistentHiddenSections.clear();
const auto hiddenSections = persistentHiddenSections;
persistentHiddenSections.clear();
clear();
q->initializeSections();
invalidateCachedSizeHint();
if (modelIsEmpty()) {
return;
}
QBitArray oldSectionHidden = sectionsHiddenToBitVector();
oldSectionHidden.resize(sectionItems.size());
bool sectionCountChanged = false;
for (int i = 0; i < persistentHiddenSections.count(); ++i) {
QModelIndex index = persistentHiddenSections.at(i);
for (const auto &index : hiddenSections) {
if (index.isValid()) {
const int logical = (orientation == Qt::Horizontal
? index.column()
: index.row());
q->setSectionHidden(logical, true);
oldSectionHidden.setBit(logical, false);
} else if (!sectionCountChanged && (modelSectionCount() != sectionCount())) {
sectionCountChanged = true;
break;
}
}
persistentHiddenSections.clear();
for (int i = 0; i < oldSectionHidden.count(); ++i) {
if (oldSectionHidden.testBit(i))
q->setSectionHidden(i, false);
}
// the number of sections changed; we need to reread the state of the model
if (sectionCountChanged)
q->initializeSections();
}
/*!

View File

@ -1397,6 +1397,9 @@ void QTableView::paintEvent(QPaintEvent *event)
} else {
dirtyArea.setRight(qMin(dirtyArea.right(), int(x)));
}
// dirtyArea may be invalid when the horizontal header is not stretched
if (!dirtyArea.isValid())
continue;
// get the horizontal start and end visual sections
int left = horizontalHeader->visualIndexAt(dirtyArea.left());

View File

@ -736,7 +736,10 @@ void QTreeView::dataChanged(const QModelIndex &topLeft, const QModelIndex &botto
void QTreeView::hideColumn(int column)
{
Q_D(QTreeView);
if (d->header->isSectionHidden(column))
return;
d->header->hideSection(column);
doItemsLayout();
}
/*!
@ -747,7 +750,10 @@ void QTreeView::hideColumn(int column)
void QTreeView::showColumn(int column)
{
Q_D(QTreeView);
if (!d->header->isSectionHidden(column))
return;
d->header->showSection(column);
doItemsLayout();
}
/*!
@ -1008,11 +1014,16 @@ void QTreeView::keyboardSearch(const QString &search)
if (!d->model->rowCount(d->root) || !d->model->columnCount(d->root))
return;
// Do a relayout nows, so that we can utilize viewItems
d->executePostedLayout();
if (d->viewItems.isEmpty())
return;
QModelIndex start;
if (currentIndex().isValid())
start = currentIndex();
else
start = d->model->index(0, 0, d->root);
start = d->viewItems.at(0).index;
bool skipRow = false;
bool keyboardTimeWasValid = d->keyboardInputTime.isValid();
@ -1040,13 +1051,16 @@ void QTreeView::keyboardSearch(const QString &search)
// skip if we are searching for the same key or a new search started
if (skipRow) {
if (indexBelow(start).isValid())
if (indexBelow(start).isValid()) {
start = indexBelow(start);
else
start = d->model->index(0, start.column(), d->root);
} else {
const int origCol = start.column();
start = d->viewItems.at(0).index;
if (origCol != start.column())
start = start.sibling(start.row(), origCol);
}
}
d->executePostedLayout();
int startIndex = d->viewIndex(start);
if (startIndex <= -1)
return;

View File

@ -476,8 +476,10 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem,
break;
if (option->state & State_Open)
drawPrimitive(PE_IndicatorArrowDown, option, painter, widget);
else
drawPrimitive(PE_IndicatorArrowRight, option, painter, widget);
else {
const bool reverse = (option->direction == Qt::RightToLeft);
drawPrimitive(reverse ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight, option, painter, widget);
}
break;
}
#if QT_CONFIG(tabbar)

View File

@ -1119,6 +1119,8 @@ static bool waitForPopup(QToolBar *tb, QWidget *popup)
static void enableMacToolBar(QToolBar *toolbar, bool enable)
{
QPlatformNativeInterface *nativeInterface = QApplication::platformNativeInterface();
if (!nativeInterface)
return;
QPlatformNativeInterface::NativeResourceForIntegrationFunction function =
nativeInterface->nativeResourceFunctionForIntegration("setContentBorderAreaEnabled");
if (!function)

View File

@ -157,7 +157,13 @@ if (NOT CMAKE_VERSION VERSION_LESS 2.8.11 AND NOT NO_WIDGETS)
expect_pass(test_interface)
endif()
if (NOT CMAKE_VERSION VERSION_LESS 2.8.12)
expect_pass(test_interface_link_libraries)
expect_pass(test_moc_macro_target)
expect_pass(test_interface_link_libraries)
expect_pass(test_moc_macro_target)
if (NOT CMAKE_VERSION VERSION_LESS 3.8)
# With earlier CMake versions, this test would simply run moc multiple times and lead to:
# /usr/bin/ld: error: CMakeFiles/mywidget.dir/mywidget_automoc.cpp.o: multiple definition of 'MyWidget::qt_static_metacall(QObject*, QMetaObject::Call, int, void**)'
# /usr/bin/ld: CMakeFiles/mywidget.dir/moc_mywidget.cpp.o: previous definition here
# Reason: SKIP_* properties were added in CMake 3.8 only
expect_pass(test_QTBUG-63422)
endif()

View File

@ -0,0 +1,30 @@
cmake_minimum_required(VERSION 2.8)
project(test_dependent_modules)
find_package(Qt5Widgets REQUIRED)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
# make sure CMP0071 warnings cause a test failure
set(CMAKE_SUPPRESS_DEVELOPER_ERRORS FALSE CACHE INTERNAL "" FORCE)
qt5_wrap_cpp(moc_files mywidget.h)
qt5_wrap_ui(ui_files mywidget.ui)
qt5_add_resources(qrc_files res.qrc)
add_executable(mywidget
# source files
mywidget.cpp
mywidget.h
mywidget.ui
res.qrc
# generated files
${moc_files}
${ui_files}
${qrc_files}
)
target_link_libraries(mywidget ${Qt5Widgets_LIBRARIES})

View File

@ -0,0 +1,43 @@
/****************************************************************************
**
** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Kevin Funk <kevin.funk@kdab.com>
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "mywidget.h"
#include "ui_mywidget.h"
MyWidget::MyWidget(QWidget *parent)
: QWidget(parent)
{
emit someSignal();
}
int main(int argc, char **argv)
{
QApplication app(argc, argv);
MyWidget myWidget;
return 0;
}

View File

@ -0,0 +1,52 @@
/****************************************************************************
**
** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Kevin Funk <kevin.funk@kdab.com>
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef MYWIDGET_H
#define MYWIDGET_H
#include <QWidget>
namespace Ui
{
class MyWidget;
}
class MyWidget : public QWidget
{
Q_OBJECT
public:
MyWidget(QWidget *parent = nullptr);
signals:
void someSignal();
private:
Ui::MyWidget *ui = nullptr;
};
#endif

View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit"/>
</item>
<item>
<widget class="QTextEdit" name="textEdit"/>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,4 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
</qresource>
</RCC>

View File

@ -290,6 +290,18 @@ void tst_QFlags::testSetFlags()
btn.setFlag(Qt::LeftButton, false);
QVERIFY(!btn.testFlag(Qt::LeftButton));
QVERIFY(!btn.testFlag(Qt::MidButton));
MyStrictFlags flags;
flags.setFlag(MyStrictEnum::StrictOne);
flags.setFlag(MyStrictEnum::StrictTwo, true);
QVERIFY(flags.testFlag(MyStrictEnum::StrictOne));
QVERIFY(flags.testFlag(MyStrictEnum::StrictTwo));
QVERIFY(!flags.testFlag(MyStrictEnum::StrictFour));
flags.setFlag(MyStrictEnum::StrictTwo, false);
QVERIFY(flags.testFlag(MyStrictEnum::StrictOne));
QVERIFY(!flags.testFlag(MyStrictEnum::StrictTwo));
QVERIFY(!flags.testFlag(MyStrictEnum::StrictFour));
}
// (statically) check QTypeInfo for QFlags instantiations:

View File

@ -197,10 +197,22 @@ private slots:
// Check whether QT_LOGGING_CONF is picked up from environment
//
qputenv("QT_LOGGING_CONF", QFINDTESTDATA("qtlogging.ini").toLocal8Bit());
Q_ASSERT(!qApp); // Rules should not require an app to resolve
QLoggingRegistry registry;
registry.init();
qputenv("QT_LOGGING_RULES", "qt.foo.bar=true");
QLoggingCategory qtEnabledByLoggingRule("qt.foo.bar");
QCOMPARE(qtEnabledByLoggingRule.isDebugEnabled(), true);
QLoggingCategory qtDisabledByDefault("qt.foo.baz");
QCOMPARE(qtDisabledByDefault.isDebugEnabled(), false);
QLoggingRegistry &registry = *QLoggingRegistry::instance();
QCOMPARE(registry.ruleSets[QLoggingRegistry::ApiRules].size(), 0);
QCOMPARE(registry.ruleSets[QLoggingRegistry::ConfigRules].size(), 0);
QCOMPARE(registry.ruleSets[QLoggingRegistry::EnvironmentRules].size(), 1);
qunsetenv("QT_LOGGING_RULES");
qputenv("QT_LOGGING_CONF", QFINDTESTDATA("qtlogging.ini").toLocal8Bit());
registry.initalizeRules();
QCOMPARE(registry.ruleSets[QLoggingRegistry::ApiRules].size(), 0);
QCOMPARE(registry.ruleSets[QLoggingRegistry::ConfigRules].size(), 0);
@ -208,7 +220,7 @@ private slots:
// check that QT_LOGGING_RULES take precedence
qputenv("QT_LOGGING_RULES", "Digia.*=true");
registry.init();
registry.initalizeRules();
QCOMPARE(registry.ruleSets[QLoggingRegistry::EnvironmentRules].size(), 2);
QCOMPARE(registry.ruleSets[QLoggingRegistry::EnvironmentRules].at(1).enabled, true);
}
@ -234,7 +246,7 @@ private slots:
file.close();
QLoggingRegistry registry;
registry.init();
registry.initalizeRules();
QCOMPARE(registry.ruleSets[QLoggingRegistry::ConfigRules].size(), 1);
// remove file again
@ -300,6 +312,6 @@ private slots:
}
};
QTEST_MAIN(tst_QLoggingRegistry)
QTEST_APPLESS_MAIN(tst_QLoggingRegistry)
#include "tst_qloggingregistry.moc"

View File

@ -41,6 +41,8 @@ private slots:
void tryAcquireWithTimeout_data();
void tryAcquireWithTimeout();
void tryAcquireWithTimeoutStarvation();
void tryAcquireWithTimeoutForever_data();
void tryAcquireWithTimeoutForever();
void producerConsumer();
void raii();
};
@ -156,21 +158,25 @@ void tst_QSemaphore::tryAcquire()
semaphore.release();
QCOMPARE(semaphore.available(), 1);
QVERIFY(!semaphore.tryAcquire(2));
QVERIFY(!semaphore.tryAcquire(2, 0));
QCOMPARE(semaphore.available(), 1);
semaphore.release();
QCOMPARE(semaphore.available(), 2);
QVERIFY(!semaphore.tryAcquire(3));
QVERIFY(!semaphore.tryAcquire(3, 0));
QCOMPARE(semaphore.available(), 2);
semaphore.release(10);
QCOMPARE(semaphore.available(), 12);
QVERIFY(!semaphore.tryAcquire(100));
QVERIFY(!semaphore.tryAcquire(100, 0));
QCOMPARE(semaphore.available(), 12);
semaphore.release(10);
QCOMPARE(semaphore.available(), 22);
QVERIFY(!semaphore.tryAcquire(100));
QVERIFY(!semaphore.tryAcquire(100, 0));
QCOMPARE(semaphore.available(), 22);
QVERIFY(semaphore.tryAcquire());
@ -179,23 +185,38 @@ void tst_QSemaphore::tryAcquire()
QVERIFY(semaphore.tryAcquire());
QCOMPARE(semaphore.available(), 20);
semaphore.release(2);
QVERIFY(semaphore.tryAcquire(1, 0));
QCOMPARE(semaphore.available(), 21);
QVERIFY(semaphore.tryAcquire(1, 0));
QCOMPARE(semaphore.available(), 20);
QVERIFY(semaphore.tryAcquire(10));
QCOMPARE(semaphore.available(), 10);
semaphore.release(10);
QVERIFY(semaphore.tryAcquire(10, 0));
QCOMPARE(semaphore.available(), 10);
QVERIFY(semaphore.tryAcquire(10));
QCOMPARE(semaphore.available(), 0);
// should not be able to acquire more
QVERIFY(!semaphore.tryAcquire());
QVERIFY(!semaphore.tryAcquire(1, 0));
QCOMPARE(semaphore.available(), 0);
QVERIFY(!semaphore.tryAcquire());
QVERIFY(!semaphore.tryAcquire(1, 0));
QCOMPARE(semaphore.available(), 0);
QVERIFY(!semaphore.tryAcquire(10));
QVERIFY(!semaphore.tryAcquire(10, 0));
QCOMPARE(semaphore.available(), 0);
QVERIFY(!semaphore.tryAcquire(10));
QVERIFY(!semaphore.tryAcquire(10, 0));
QCOMPARE(semaphore.available(), 0);
}
@ -345,6 +366,48 @@ void tst_QSemaphore::tryAcquireWithTimeoutStarvation()
QVERIFY(consumer.wait());
}
void tst_QSemaphore::tryAcquireWithTimeoutForever_data()
{
QTest::addColumn<int>("timeout");
QTest::newRow("-1") << -1;
// tryAcquire is documented to take any negative value as "forever"
QTest::newRow("INT_MIN") << INT_MIN;
}
void tst_QSemaphore::tryAcquireWithTimeoutForever()
{
enum { WaitTime = 1000 };
struct Thread : public QThread {
QSemaphore sem;
void run() override
{
QTest::qWait(WaitTime);
sem.release(2);
}
};
QFETCH(int, timeout);
Thread t;
// sanity check it works if we can immediately acquire
t.sem.release(11);
QVERIFY(t.sem.tryAcquire(1, timeout));
QVERIFY(t.sem.tryAcquire(10, timeout));
// verify that we do wait for at least WaitTime if we can't acquire immediately
QElapsedTimer timer;
timer.start();
t.start();
QVERIFY(t.sem.tryAcquire(1, timeout));
QVERIFY(timer.elapsed() >= WaitTime);
QVERIFY(t.wait());
QCOMPARE(t.sem.available(), 1);
}
const char alphabet[] = "ACGTH";
const int AlphabetSize = sizeof(alphabet) - 1;

View File

@ -95,6 +95,7 @@ private slots:
void stackSize();
void stressTest();
void takeAllAndIncreaseMaxThreadCount();
void waitForDoneAfterTake();
private:
QMutex m_functionTestMutex;
@ -1267,5 +1268,72 @@ void tst_QThreadPool::takeAllAndIncreaseMaxThreadCount() {
delete task3;
}
void tst_QThreadPool::waitForDoneAfterTake()
{
class Task : public QRunnable
{
public:
Task(QSemaphore *mainBarrier, QSemaphore *threadBarrier)
: m_mainBarrier(mainBarrier)
, m_threadBarrier(threadBarrier)
{}
void run()
{
m_mainBarrier->release();
m_threadBarrier->acquire();
}
private:
QSemaphore *m_mainBarrier = nullptr;
QSemaphore *m_threadBarrier = nullptr;
};
int threadCount = 4;
// Blocks the main thread from releasing the threadBarrier before all run() functions have started
QSemaphore mainBarrier;
// Blocks the tasks from completing their run function
QSemaphore threadBarrier;
QThreadPool manager;
manager.setMaxThreadCount(threadCount);
// Fill all the threads with runnables that wait for the threadBarrier
for (int i = 0; i < threadCount; i++) {
auto *task = new Task(&mainBarrier, &threadBarrier);
manager.start(task);
}
QVERIFY(manager.activeThreadCount() == manager.maxThreadCount());
// Add runnables that are immediately removed from the pool queue.
// This sets the queue elements to nullptr in QThreadPool and we want to test that
// the threads keep going through the queue after encountering a nullptr.
for (int i = 0; i < threadCount; i++) {
QRunnable *runnable = createTask(emptyFunct);
manager.start(runnable);
QVERIFY(manager.tryTake(runnable));
}
// Add another runnable that will not be removed
manager.start(createTask(emptyFunct));
// Wait for the first runnables to start
mainBarrier.acquire(threadCount);
QVERIFY(mainBarrier.available() == 0);
QVERIFY(threadBarrier.available() == 0);
// Release runnables that are waiting and expect all runnables to complete
threadBarrier.release(threadCount);
// Using qFatal instead of QVERIFY to force exit if threads are still running after timeout.
// Otherwise, QCoreApplication will still wait for the stale threads and never exit the test.
if (!manager.waitForDone(5 * 60 * 1000))
qFatal("waitForDone returned false. Aborting to stop background threads.");
}
QTEST_MAIN(tst_QThreadPool);
#include "tst_qthreadpool.moc"

View File

@ -630,7 +630,7 @@ protected:
Q_ASSERT(!client.isNull());
// we need to emulate the bytesWrittenSlot call if the data is empty.
if (dataToTransmit.size() == 0) {
QMetaObject::invokeMethod(this, "bytesWrittenSlot", Qt::QueuedConnection);
emit client->bytesWritten(0);
} else {
client->write(dataToTransmit);
// FIXME: For SSL connections, if we don't flush the socket, the
@ -667,23 +667,26 @@ private slots:
#ifndef QT_NO_SSL
void slotSslErrors(const QList<QSslError>& errors)
{
Q_ASSERT(!client.isNull());
qDebug() << "slotSslErrors" << client->errorString() << errors;
QTcpSocket *currentClient = qobject_cast<QTcpSocket *>(sender());
Q_ASSERT(currentClient);
qDebug() << "slotSslErrors" << currentClient->errorString() << errors;
}
#endif
void slotError(QAbstractSocket::SocketError err)
{
if (client.isNull())
qDebug() << "slotError" << err;
else
qDebug() << "slotError" << err << client->errorString();
QTcpSocket *currentClient = qobject_cast<QTcpSocket *>(sender());
Q_ASSERT(currentClient);
qDebug() << "slotError" << err << currentClient->errorString();
}
public slots:
void readyReadSlot()
{
Q_ASSERT(!client.isNull());
QTcpSocket *currentClient = qobject_cast<QTcpSocket *>(sender());
Q_ASSERT(currentClient);
if (currentClient != client)
client = currentClient;
receivedData += client->readAll();
const int doubleEndlPos = receivedData.indexOf("\r\n\r\n");
@ -8307,11 +8310,23 @@ void tst_QNetworkReply::ioHttpRedirectErrors()
QNetworkReplyPtr reply(manager.get(request));
if (localhost.scheme() == "https")
reply.data()->ignoreSslErrors();
QSignalSpy spy(reply.data(), SIGNAL(error(QNetworkReply::NetworkError)));
QCOMPARE(waitForFinish(reply), int(Failure));
QEventLoop eventLoop;
QTimer watchDog;
watchDog.setSingleShot(true);
QCOMPARE(spy.count(), 1);
reply->connect(reply.data(), QOverload<QNetworkReply::NetworkError>().of(&QNetworkReply::error),
[&eventLoop](QNetworkReply::NetworkError){
eventLoop.exit(Failure);
});
watchDog.connect(&watchDog, &QTimer::timeout, [&eventLoop](){
eventLoop.exit(Timeout);
});
watchDog.start(5000);
QCOMPARE(eventLoop.exec(), int(Failure));
QCOMPARE(reply->error(), error);
}

View File

@ -43,7 +43,7 @@ private slots:
void tst_QDnsLookup_Appless::noApplication()
{
QTest::ignoreMessage(QtWarningMsg, "QDnsLookup requires a QCoreApplication");
QDnsLookup dns(QDnsLookup::A, "a-single.test.macieira.org");
QDnsLookup dns(QDnsLookup::A, "a-single.test.qt-project.org");
dns.lookup();
}
@ -53,7 +53,7 @@ void tst_QDnsLookup_Appless::recreateApplication()
char **argv = 0;
for (int i = 0; i < 10; ++i) {
QCoreApplication app(argc, argv);
QDnsLookup dns(QDnsLookup::A, "a-single.test.macieira.org");
QDnsLookup dns(QDnsLookup::A, "a-single.test.qt-project.org");
dns.lookup();
if (!dns.isFinished()) {
QObject::connect(&dns, SIGNAL(finished()),

View File

@ -72,7 +72,7 @@
#include "../../../network-settings.h"
#define TEST_DOMAIN ".test.macieira.org"
#define TEST_DOMAIN ".test.qt-project.org"
class tst_QHostInfo : public QObject

View File

@ -6,8 +6,6 @@ windows
windows
[invalidProxy:socks5-on-http]
windows
[disconnectWhileLookingUp]
windows
[timeoutConnect:ip]
windows
]

View File

@ -1445,8 +1445,15 @@ void tst_QTcpSocket::disconnectWhileLookingUp()
}
// let anything queued happen
QEventLoop loop;
QTimer::singleShot(50, &loop, SLOT(quit()));
// If 'doClose' is false then we called '::waitForDisconnected' earlier, meaning
// we are already 'Unconnected'. So we don't need to wait for any potentially slow host lookups.
QTimer::singleShot(doClose ? 4000 : 50, &loop, SLOT(quit()));
connect(socket, &QTcpSocket::stateChanged, [&loop](QAbstractSocket::SocketState state) {
if (state == QAbstractSocket::UnconnectedState)
loop.exit(); // we don't need to wait for the timer to expire; we're done.
});
loop.exec();
// recheck

View File

@ -1,6 +1,4 @@
windows
[waitForConnectedEncryptedReadyRead:WithSocks5ProxyAuth]
*
[protocolServerSide:ssl3-any]
rhel-7.2
[protocolServerSide:tls1.0-any]

View File

@ -1601,7 +1601,12 @@ void tst_QSslSocket::waitForConnectedEncryptedReadyRead()
QFETCH_GLOBAL(bool, setProxy);
if (setProxy && !socket->waitForEncrypted(10000))
QSKIP("Skipping flaky test - See QTBUG-29941");
QVERIFY(socket->waitForReadyRead(10000));
// We only do this if we have no bytes available to read already because readyRead will
// not be emitted again.
if (socket->bytesAvailable() == 0)
QVERIFY(socket->waitForReadyRead(10000));
QVERIFY(!socket->peerCertificate().isNull());
QVERIFY(!socket->peerCertificateChain().isEmpty());
}

View File

@ -210,6 +210,7 @@ private slots:
void QTBUG12268_hiddenMovedSectionSorting();
void QTBUG14242_hideSectionAutoSize();
void QTBUG50171_visualRegionForSwappedItems();
void QTBUG53221_assertShiftHiddenRow();
void ensureNoIndexAtLength();
void offsetConsistent();
@ -2384,6 +2385,54 @@ void tst_QHeaderView::QTBUG50171_visualRegionForSwappedItems()
headerView.testVisualRegionForSelection();
}
class QTBUG53221_Model : public QAbstractItemModel
{
public:
void insertRowAtBeginning()
{
Q_EMIT layoutAboutToBeChanged();
m_displayNames.insert(0, QStringLiteral("Item %1").arg(m_displayNames.count()));
// Rows are always inserted at the beginning, so move all others.
foreach (const QModelIndex &persIndex, persistentIndexList())
{
// The vertical header view will have a persistent index stored here on the second call to insertRowAtBeginning.
changePersistentIndex(persIndex, index(persIndex.row() + 1, persIndex.column(), persIndex.parent()));
}
Q_EMIT layoutChanged();
}
QVariant data(const QModelIndex &index, int role) const override
{
return (role == Qt::DisplayRole) ? m_displayNames.at(index.row()) : QVariant();
}
QModelIndex index(int row, int column, const QModelIndex &) const override { return createIndex(row, column); }
QModelIndex parent(const QModelIndex &) const override { return QModelIndex(); }
int rowCount(const QModelIndex &) const override { return m_displayNames.count(); }
int columnCount(const QModelIndex &) const override { return 1; }
private:
QStringList m_displayNames;
};
void tst_QHeaderView::QTBUG53221_assertShiftHiddenRow()
{
QTableView tableView;
QTBUG53221_Model modelTableView;
tableView.setModel(&modelTableView);
modelTableView.insertRowAtBeginning();
tableView.setRowHidden(0, true);
QCOMPARE(tableView.verticalHeader()->isSectionHidden(0), true);
modelTableView.insertRowAtBeginning();
QCOMPARE(tableView.verticalHeader()->isSectionHidden(0), false);
QCOMPARE(tableView.verticalHeader()->isSectionHidden(1), true);
modelTableView.insertRowAtBeginning();
QCOMPARE(tableView.verticalHeader()->isSectionHidden(0), false);
QCOMPARE(tableView.verticalHeader()->isSectionHidden(1), false);
QCOMPARE(tableView.verticalHeader()->isSectionHidden(2), true);
}
void protected_QHeaderView::testVisualRegionForSelection()
{
QRegion r = visualRegionForSelection(QItemSelection(model()->index(1, 0), model()->index(1, 2)));

View File

@ -197,6 +197,7 @@ private slots:
void taskQTBUG_37813_crash();
void taskQTBUG_45697_crash();
void taskQTBUG_7232_AllowUserToControlSingleStep();
void taskQTBUG_8376();
void testInitialFocus();
};
@ -1087,6 +1088,103 @@ void tst_QTreeView::keyboardSearch()
// The item that starts with B is selected.
view.keyboardSearch(QLatin1String("B"));
QVERIFY(view.selectionModel()->isSelected(model.index(1, 0)));
// Test that it wraps round
model.appendRow(new QStandardItem("Andy"));
QTest::qWait(QApplication::keyboardInputInterval() * 2);
view.keyboardSearch(QLatin1String("A"));
QVERIFY(view.selectionModel()->isSelected(model.index(3, 0)));
QTest::qWait(QApplication::keyboardInputInterval() * 2);
view.keyboardSearch(QLatin1String("A"));
QVERIFY(view.selectionModel()->isSelected(model.index(0, 0)));
QTest::qWait(QApplication::keyboardInputInterval() * 2);
view.keyboardSearch(QLatin1String("A"));
QVERIFY(view.selectionModel()->isSelected(model.index(3, 0)));
// Test that it handles the case where the first item is hidden correctly
model.insertRow(0, new QStandardItem("Hidden item"));
view.setRowHidden(0, QModelIndex(), true);
QTest::qWait(QApplication::keyboardInputInterval() * 2);
view.keyboardSearch(QLatin1String("A"));
QVERIFY(view.selectionModel()->isSelected(model.index(1, 0)));
QTest::qWait(QApplication::keyboardInputInterval() * 2);
view.keyboardSearch(QLatin1String("A"));
QVERIFY(view.selectionModel()->isSelected(model.index(4, 0)));
QTest::qWait(QApplication::keyboardInputInterval() * 2);
view.keyboardSearch(QLatin1String("A"));
QVERIFY(view.selectionModel()->isSelected(model.index(1, 0)));
QTest::qWait(QApplication::keyboardInputInterval() * 2);
model.clear();
view.setCurrentIndex(QModelIndex());
QList<QStandardItem *> items = { new QStandardItem("Andreas"), new QStandardItem("Alicia") };
model.appendRow(items);
items = { new QStandardItem("Baldrian"), new QStandardItem("Belinda") };
model.appendRow(items);
items = { new QStandardItem("Cecilie"), new QStandardItem("Claire") };
model.appendRow(items);
QVERIFY(!view.selectionModel()->hasSelection());
QVERIFY(!view.selectionModel()->isSelected(model.index(0, 0)));
// We want to search on the 2nd column so we have to force it to have
// an index in that column as a starting point
view.setCurrentIndex(QModelIndex(model.index(0, 1)));
// Second item in first row is selected
view.keyboardSearch(QLatin1String("A"));
QTRY_VERIFY(view.selectionModel()->isSelected(model.index(0, 1)));
QVERIFY(view.currentIndex() == model.index(0, 1));
// Second item in first row is still selected
view.keyboardSearch(QLatin1String("l"));
QVERIFY(view.selectionModel()->isSelected(model.index(0, 1)));
QCOMPARE(view.currentIndex(), model.index(0, 1));
// No "AnB" item - keep the same selection.
view.keyboardSearch(QLatin1String("B"));
QVERIFY(view.selectionModel()->isSelected(model.index(0, 1)));
QCOMPARE(view.currentIndex(), model.index(0, 1));
// Wait a bit.
QTest::qWait(QApplication::keyboardInputInterval() * 2);
// The item that starts with B is selected.
view.keyboardSearch(QLatin1String("B"));
QVERIFY(view.selectionModel()->isSelected(model.index(1, 1)));
QCOMPARE(view.currentIndex(), model.index(1, 1));
// Test that it wraps round
items = { new QStandardItem("Andy"), new QStandardItem("Adele") };
model.appendRow(items);
QTest::qWait(QApplication::keyboardInputInterval() * 2);
view.keyboardSearch(QLatin1String("A"));
QVERIFY(view.selectionModel()->isSelected(model.index(3, 1)));
QCOMPARE(view.currentIndex(), model.index(3, 1));
QTest::qWait(QApplication::keyboardInputInterval() * 2);
view.keyboardSearch(QLatin1String("A"));
QVERIFY(view.selectionModel()->isSelected(model.index(0, 1)));
QCOMPARE(view.currentIndex(), model.index(0, 1));
QTest::qWait(QApplication::keyboardInputInterval() * 2);
view.keyboardSearch(QLatin1String("A"));
QVERIFY(view.selectionModel()->isSelected(model.index(3, 1)));
QCOMPARE(view.currentIndex(), model.index(3, 1));
// Test that it handles the case where the first item is hidden correctly
model.insertRow(0, new QStandardItem("Hidden item"));
view.setRowHidden(0, QModelIndex(), true);
QTest::qWait(QApplication::keyboardInputInterval() * 2);
view.keyboardSearch(QLatin1String("A"));
QVERIFY(view.selectionModel()->isSelected(model.index(1, 1)));
QCOMPARE(view.currentIndex(), model.index(1, 1));
QTest::qWait(QApplication::keyboardInputInterval() * 2);
view.keyboardSearch(QLatin1String("A"));
QVERIFY(view.selectionModel()->isSelected(model.index(4, 1)));
QCOMPARE(view.currentIndex(), model.index(4, 1));
QTest::qWait(QApplication::keyboardInputInterval() * 2);
view.keyboardSearch(QLatin1String("A"));
QVERIFY(view.selectionModel()->isSelected(model.index(1, 1)));
QCOMPARE(view.currentIndex(), model.index(1, 1));
}
void tst_QTreeView::keyboardSearchMultiColumn()
@ -4511,5 +4609,50 @@ void tst_QTreeView::fetchMoreOnScroll()
QCOMPARE(im.item(19)->rowCount(), 20);
}
static void fillModeltaskQTBUG_8376(QAbstractItemModel &model)
{
model.insertRow(0);
model.insertColumn(0);
model.insertColumn(1);
QModelIndex index = model.index(0, 0);
model.setData(index, "Level0");
{
model.insertRow(0, index);
model.insertRow(1, index);
model.insertColumn(0, index);
model.insertColumn(1, index);
QModelIndex idx;
idx = model.index(0, 0, index);
model.setData(idx, "Level1");
idx = model.index(0, 1, index);
model.setData(idx, "very\nvery\nhigh\ncell");
}
}
void tst_QTreeView::taskQTBUG_8376()
{
QTreeView tv;
QStandardItemModel model;
fillModeltaskQTBUG_8376(model);
tv.setModel(&model);
tv.expandAll(); // init layout
QModelIndex idxLvl0 = model.index(0, 0);
QModelIndex idxLvl1 = model.index(0, 1, idxLvl0);
const int rowHeightLvl0 = tv.rowHeight(idxLvl0);
const int rowHeightLvl1Visible = tv.rowHeight(idxLvl1);
QVERIFY(rowHeightLvl0 < rowHeightLvl1Visible);
tv.hideColumn(1);
const int rowHeightLvl1Hidden = tv.rowHeight(idxLvl1);
QCOMPARE(rowHeightLvl0, rowHeightLvl1Hidden);
tv.showColumn(1);
const int rowHeightLvl1Visible2 = tv.rowHeight(idxLvl1);
QCOMPARE(rowHeightLvl1Visible, rowHeightLvl1Visible2);
}
QTEST_MAIN(tst_QTreeView)
#include "tst_qtreeview.moc"

View File

@ -28,7 +28,7 @@
#include "menuramaapplication.h"
MenuramaApplication::MenuramaApplication(int argc, char **argv)
MenuramaApplication::MenuramaApplication(int &argc, char **argv)
: QApplication (argc, argv)
{
#if 0

View File

@ -36,7 +36,7 @@
class MenuramaApplication : public QApplication
{
public:
MenuramaApplication(int argc, char **argv);
MenuramaApplication(int &argc, char **argv);
void addDynMenu(QLatin1String title, QMenu *parentMenu);
QAction *findAction(QLatin1String title, QMenu *parentMenu);