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
1
.gitignore
vendored
@ -245,6 +245,7 @@ tags
|
||||
*.gcda
|
||||
*.gcno
|
||||
*.lib
|
||||
!Info.plist.lib
|
||||
*.o
|
||||
*.obj
|
||||
*.orig
|
||||
|
@ -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]
|
||||
|
@ -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
@ -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.
|
Before Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 40 KiB |
BIN
doc/src/images/validators.png
Normal file
After Width: | Height: | Size: 11 KiB |
@ -2,7 +2,6 @@ TEMPLATE = \
|
||||
subdirs
|
||||
SUBDIRS += \
|
||||
animatedtiles \
|
||||
appchooser \
|
||||
easing \
|
||||
moveblocks \
|
||||
states \
|
||||
|
Before Width: | Height: | Size: 5.3 KiB |
Before Width: | Height: | Size: 4.8 KiB |
@ -1,8 +0,0 @@
|
||||
QT += widgets
|
||||
|
||||
SOURCES = main.cpp
|
||||
RESOURCES = appchooser.qrc
|
||||
|
||||
# install
|
||||
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/animation/appchooser
|
||||
INSTALLS += target
|
@ -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>
|
Before Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 8.0 KiB |
@ -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"
|
Before Width: | Height: | Size: 8.5 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 17 KiB |
@ -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
|
||||
|
||||
*/
|
@ -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
|
||||
|
@ -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
|
||||
*/
|
@ -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
|
||||
|
@ -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.
|
||||
|
||||
*/
|
||||
|
||||
|
@ -31,4 +31,6 @@
|
||||
\ingroup examples-widgets
|
||||
\brief The Validators example shows the signal emission behavior of input
|
||||
validators.
|
||||
|
||||
\borderedimage validators.png
|
||||
*/
|
||||
|
@ -2,5 +2,4 @@ TEMPLATE = \
|
||||
subdirs
|
||||
SUBDIRS = \
|
||||
blurpicker \
|
||||
lighting \
|
||||
fademessage
|
||||
|
@ -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 */)
|
||||
{
|
||||
}
|
@ -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
|
@ -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
|
@ -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();
|
||||
}
|
@ -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");
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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)) {
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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()) {
|
||||
|
@ -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()) {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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()
|
||||
|
@ -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}
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 \
|
||||
|
@ -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()
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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, ^{
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 21 KiB |
@ -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();
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -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());
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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()
|
||||
|
30
tests/auto/cmake/test_QTBUG-63422/CMakeLists.txt
Normal 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})
|
43
tests/auto/cmake/test_QTBUG-63422/mywidget.cpp
Normal 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;
|
||||
}
|
52
tests/auto/cmake/test_QTBUG-63422/mywidget.h
Normal 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
|
34
tests/auto/cmake/test_QTBUG-63422/mywidget.ui
Normal 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>
|
4
tests/auto/cmake/test_QTBUG-63422/res.qrc
Normal file
@ -0,0 +1,4 @@
|
||||
<!DOCTYPE RCC><RCC version="1.0">
|
||||
<qresource>
|
||||
</qresource>
|
||||
</RCC>
|
@ -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:
|
||||
|
@ -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 ®istry = *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"
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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()),
|
||||
|
@ -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
|
||||
|
@ -6,8 +6,6 @@ windows
|
||||
windows
|
||||
[invalidProxy:socks5-on-http]
|
||||
windows
|
||||
[disconnectWhileLookingUp]
|
||||
windows
|
||||
[timeoutConnect:ip]
|
||||
windows
|
||||
]
|
||||
|
@ -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
|
||||
|
@ -1,6 +1,4 @@
|
||||
windows
|
||||
[waitForConnectedEncryptedReadyRead:WithSocks5ProxyAuth]
|
||||
*
|
||||
[protocolServerSide:ssl3-any]
|
||||
rhel-7.2
|
||||
[protocolServerSide:tls1.0-any]
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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)));
|
||||
|
@ -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"
|
||||
|
@ -28,7 +28,7 @@
|
||||
|
||||
#include "menuramaapplication.h"
|
||||
|
||||
MenuramaApplication::MenuramaApplication(int argc, char **argv)
|
||||
MenuramaApplication::MenuramaApplication(int &argc, char **argv)
|
||||
: QApplication (argc, argv)
|
||||
{
|
||||
#if 0
|
||||
|
@ -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);
|
||||
|
||||
|