Merge remote-tracking branch 'origin/5.10' into dev
Conflicts: src/plugins/platforms/windows/qwindowsmousehandler.cpp src/plugins/platforms/xcb/qxcbimage.cpp tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp tests/manual/qtabletevent/regular_widgets/main.cpp Done-with: Friedemann Kleint<Friedemann.Kleint@qt.io> Done-with: Mårten Nordheim<marten.nordheim@qt.io> Change-Id: I5b2499513a92c590ed0756f7d2e93c35a64b7f30
This commit is contained in:
commit
fa9d12f4a2
1
.gitignore
vendored
1
.gitignore
vendored
@ -28,6 +28,7 @@
|
|||||||
/src/corelib/global/qconfig_p.h
|
/src/corelib/global/qconfig_p.h
|
||||||
/bin/qt.conf
|
/bin/qt.conf
|
||||||
/bin/qmake
|
/bin/qmake
|
||||||
|
/bin/qvkgen
|
||||||
/qmake/qmake
|
/qmake/qmake
|
||||||
qt*-config.h
|
qt*-config.h
|
||||||
qt*-config_p.h
|
qt*-config_p.h
|
||||||
|
259
dist/changes-5.9.2
vendored
Normal file
259
dist/changes-5.9.2
vendored
Normal file
@ -0,0 +1,259 @@
|
|||||||
|
Qt 5.9.2 is a bug-fix release. It maintains both forward and backward
|
||||||
|
compatibility (source and binary) with Qt 5.9.0.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
****************************************************************************
|
||||||
|
* Important Behavior Changes *
|
||||||
|
****************************************************************************
|
||||||
|
|
||||||
|
- Building examples inside the Qt source tree while not building Qt itself
|
||||||
|
is rejected now, because this can cause hard to debug configuration
|
||||||
|
issues. If building isolated examples is needed, you may still use shadow
|
||||||
|
builds.
|
||||||
|
|
||||||
|
- This version of Qt restores compatibility with pre-5.9.0 calculation of
|
||||||
|
QCryptographicHash algorithms that were labelled "Sha3_nnn": that is,
|
||||||
|
applications compiled with old versions of Qt will continue using the
|
||||||
|
Keccak algorithm. Applications recompiled with this version will use
|
||||||
|
SHA-3, unless QT_SHA3_KECCAK_COMPAT is #define'd prior to #include
|
||||||
|
<QCryptographicHash>.
|
||||||
|
|
||||||
|
****************************************************************************
|
||||||
|
* General Notes *
|
||||||
|
****************************************************************************
|
||||||
|
|
||||||
|
Binary Compatibility Note
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
- The variable QOperatingSystemVersion::AndroidOreo was added in this
|
||||||
|
release. Code that uses this variable will not run under Qt 5.9.1. If
|
||||||
|
backwards compatibility is desired, use instead
|
||||||
|
QOperatingSystemVersion(QOperatingSystemVersion::Android, 8)
|
||||||
|
[This is similar to QOperatingSystemVersion::MacOSHighSierra added in
|
||||||
|
5.9.1]
|
||||||
|
|
||||||
|
- This version of Qt changes the values assigned to enumerations
|
||||||
|
QCryptographicHash::Sha3_nnn. Applications compiled with this version and
|
||||||
|
using those enumerations will not work with Qt 5.9.0 and 5.9.1, unless
|
||||||
|
QT_SHA3_KECCAK_COMPAT is defined.
|
||||||
|
|
||||||
|
Deprecation Notice
|
||||||
|
------------------
|
||||||
|
|
||||||
|
- Starting with Qt 5.10, IPv6 support will be mandatory for all platforms.
|
||||||
|
Systems without proper IPv6 support, such as the getaddrinfo() function
|
||||||
|
or the proper socket address structures, will not be able to build
|
||||||
|
QtNetwork anymore.
|
||||||
|
|
||||||
|
Third-Party Code
|
||||||
|
----------------
|
||||||
|
|
||||||
|
- [QTBUG-31020] zlib was updated to version 1.2.11.
|
||||||
|
- libpng was updated to version 1.6.32
|
||||||
|
|
||||||
|
****************************************************************************
|
||||||
|
* Library *
|
||||||
|
****************************************************************************
|
||||||
|
|
||||||
|
QtCore
|
||||||
|
------
|
||||||
|
|
||||||
|
- [QTBUG-61350] Fixed the conversion from string to double of the strings
|
||||||
|
"0E+1" and "0E-1" (with capital E), which QString::toDouble(),
|
||||||
|
QByteArray::toDouble() and similar functions reported as invalid.
|
||||||
|
|
||||||
|
- QFile:
|
||||||
|
* [QTBUG-57023] Reverted an incorrect change from Qt 5.9.0 that forbade
|
||||||
|
the creation and access to Alternate Data Streams on NTFS on Windows.
|
||||||
|
This means that file names containing a colon (':') are allowed again,
|
||||||
|
but note that they are not regular files.
|
||||||
|
|
||||||
|
- QFileInfo:
|
||||||
|
* [QTBUG-62802] Relative symbolic links on Windows are now resolved to
|
||||||
|
their absolute path by symLinkTarget().
|
||||||
|
|
||||||
|
- QFileSystemWatcher:
|
||||||
|
* [QTBUG-62242] Fixed a crash on Windows if this class was instantiated
|
||||||
|
before QCoreApplication was created.
|
||||||
|
* [QTBUG-61792] Fixed an issue on Windows that would cause this class not
|
||||||
|
to monitor files properly if the directory containing the monitored
|
||||||
|
files was added to the list of watched paths after the files.
|
||||||
|
|
||||||
|
- QLocale:
|
||||||
|
* [QTBUG-53565] Fixed the conversion of QTime to string form and parsing
|
||||||
|
from string form to always treat the value as the decimal fraction of
|
||||||
|
the seconds component. That is, the string format ".z" produces/parses
|
||||||
|
".2" for 200 milliseconds and ".002" for 2 milliseconds. Use of "z" or
|
||||||
|
"zzz" is discouraged outside decimal fractions to avoid surprises.
|
||||||
|
* [QTBUG-61949] Fixed bcp57Name() to return "en" for the QLocale::c()
|
||||||
|
locale. Previously, it returned "C", which is not a valid BCP47
|
||||||
|
language tag.
|
||||||
|
|
||||||
|
- QProcess:
|
||||||
|
* [QTBUG-61634] Added a workaround for a rare race-condition bug in
|
||||||
|
some C libraries that caused the child process started by QProcess to
|
||||||
|
hang after trying to launch a non-existent executable or change to a
|
||||||
|
non-existent directory.
|
||||||
|
* [QTBUG-62584] Fixed a race-condition bug that could cause
|
||||||
|
waitForXxx() functions to hang forever if a slot triggered by that
|
||||||
|
function futher started a nested event loop.
|
||||||
|
|
||||||
|
- QTimeZone:
|
||||||
|
* [QTBUG-63205] Fixed a bug that would cause QTimeZone to mis-parse
|
||||||
|
timezone files on Unix systems if they contained leap second
|
||||||
|
information.
|
||||||
|
|
||||||
|
- QVariant:
|
||||||
|
* [QTBUG-61471] Fixed QVariant to actually perform the conversions
|
||||||
|
between QVariantHash and QVariantMap in the respective .toHash() and
|
||||||
|
.toMap() functions. QVariant already reported true in .canConvert()
|
||||||
|
between those two types.
|
||||||
|
|
||||||
|
QtDBus
|
||||||
|
------
|
||||||
|
|
||||||
|
- [QTBUG-62284] Fixed a race condition in QDBusAbstractInterface that
|
||||||
|
could cause the class to never see the notification that the remote
|
||||||
|
service became available and cause isValid() to change to true.
|
||||||
|
|
||||||
|
QtGui
|
||||||
|
-----
|
||||||
|
|
||||||
|
- Text:
|
||||||
|
* [QTBUG-61520] Fixed matching of non-regular font weights for
|
||||||
|
application fonts on macOS.
|
||||||
|
|
||||||
|
QtNetwork
|
||||||
|
---------
|
||||||
|
|
||||||
|
- [QTBUG-61692] Fixed the handling of application-wide proxy settings (set
|
||||||
|
with QNetworkProxy): previously, QTcpSocket would directly fall back to
|
||||||
|
the system settings if the object-specific setting was
|
||||||
|
QNetworkProxy::DefaultProxy.
|
||||||
|
|
||||||
|
- QLocalSocket:
|
||||||
|
* [QTBUG-61643] Fixed an issue with Qt pipe-handling code that could
|
||||||
|
cause deadlocks on Windows, most often if the QLocalSocket object tried
|
||||||
|
to wait for more data during application shutdown.
|
||||||
|
|
||||||
|
QtTest
|
||||||
|
------
|
||||||
|
|
||||||
|
- Added flowId to messages when logging in TeamCity format. FlowId is used
|
||||||
|
to distinguish logging from multiple processes running in parallel.
|
||||||
|
|
||||||
|
QtWidgets
|
||||||
|
---------
|
||||||
|
|
||||||
|
- Android:
|
||||||
|
* [QTBUG-48639] Fixed label duplication for buttons when using style
|
||||||
|
sheets with the Android style.
|
||||||
|
|
||||||
|
- QLineEdit:
|
||||||
|
* [QTBUG-60319] Fixed behavior of the ImSurroundingText query.
|
||||||
|
Previously, it returned a masked text whose length may be less than
|
||||||
|
the cursor position. Now it returns unmasked text, so the text length
|
||||||
|
is always greater than or equal to the cursor position.
|
||||||
|
|
||||||
|
- QMenu:
|
||||||
|
* [QTBUG-59794] Fixed menu size issue when using high DPI on
|
||||||
|
multi-screen system.
|
||||||
|
|
||||||
|
****************************************************************************
|
||||||
|
* Compiler-specific Changes *
|
||||||
|
****************************************************************************
|
||||||
|
|
||||||
|
clang
|
||||||
|
-----
|
||||||
|
|
||||||
|
- [QTBUG-61840][QTBUG-62085] Fixed an issue that caused recent Clang
|
||||||
|
versions to print a warning about [[nodiscard].
|
||||||
|
|
||||||
|
Visual Studio
|
||||||
|
-------------
|
||||||
|
|
||||||
|
- [QTBUG-61902] Changed Qt uses of certain C++ Standard Library functions
|
||||||
|
that Visual Studio warns about. Now Qt public headers call
|
||||||
|
Microsoft-specific versions that do not produce warnings.
|
||||||
|
|
||||||
|
****************************************************************************
|
||||||
|
* Platform-specific Changes *
|
||||||
|
****************************************************************************
|
||||||
|
|
||||||
|
macOS
|
||||||
|
-----
|
||||||
|
|
||||||
|
- [QTBUG-59222] Switching focus objects inside a top level window while
|
||||||
|
composing text using dead keys or input method events would leave the
|
||||||
|
application in an inconsistent state. The composition now automatically
|
||||||
|
cancels when the focus object changes.
|
||||||
|
|
||||||
|
Windows
|
||||||
|
-------
|
||||||
|
|
||||||
|
- [QTBUG-57916] Fixed build with ANGLE and newer MinGW versions.
|
||||||
|
- [QTBUG-62083] Fixed Qt trying to steal certain events from user windows if
|
||||||
|
the event ID was WM_USER.
|
||||||
|
|
||||||
|
****************************************************************************
|
||||||
|
* Tools *
|
||||||
|
****************************************************************************
|
||||||
|
|
||||||
|
configure & build system
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
- [QTBUG-35928][QTBUG-41908][Apple] Qt can now be built using just the
|
||||||
|
Xcode Command Line Tools, without needing to install the full Xcode IDE.
|
||||||
|
- [QTBUG-55755][Windows] All Qt .exe files now include meta information,
|
||||||
|
like .dll files already did.
|
||||||
|
- [QTBUG-58012] (Re-)added a way to specify alternative ICU libraries.
|
||||||
|
- [QTBUG-62150] Fixed detection of ICU in static builds.
|
||||||
|
- [QTBUG-53537][X11] Added missing detection of Xinerama.
|
||||||
|
- [QTBUG-61731][X11] Fixed detection of AT-SPI, allowing accessibility
|
||||||
|
support to be built again.
|
||||||
|
- [X11] Fixed detection of x11-xcb with pkg-config.
|
||||||
|
- [CMake] All Qt module defines are now propagated to the config files.
|
||||||
|
|
||||||
|
qmake
|
||||||
|
-----
|
||||||
|
|
||||||
|
- [QTBUG-31034] Added qmake feature and configure option to use ccache.
|
||||||
|
- [QTBUG-48342] Fixed generation of extraneous slashes in -project mode.
|
||||||
|
- [QTBUG-55633] Fixed misparsing of some string literal concatenations
|
||||||
|
as C++11 raw strings. This affects dependency scanning.
|
||||||
|
- [QTBUG-59301][Xcode] Fixed duplicate references in project files.
|
||||||
|
- [QTBUG-59827][nmake] The 'clean' target now deletes backup files of
|
||||||
|
MSVC manifests.
|
||||||
|
- [QTBUG-60455][Android] libc++ is now used instead of libstdc++ when
|
||||||
|
building with the android-clang mkspec.
|
||||||
|
- [QTBUG-60430][iOS] Fixed handling of the deprecated variable
|
||||||
|
QMAKE_IOS_TARGETED_DEVICE_FAMILY.
|
||||||
|
- [QTBUG-60899][WinRT] Fixed capability handling for Win10 targets.
|
||||||
|
- [WinRT] Added support for new Win10 capabilities.
|
||||||
|
- [QTBUG-61335][MinGW] Worked around LTO+MRI linker issue when cross-
|
||||||
|
building from Linux.
|
||||||
|
- [QTBUG-61411][Windows] _UNICODE is now defined, consistently with VS.
|
||||||
|
- [QTBUG-61688][MSVC] Fixed compilation of precompiled headers with
|
||||||
|
CONFIG+=silent. Done by removing redundant progress messages.
|
||||||
|
- [QTBUG-61690][QTBUG-61735] Fixed detection of compiler default search
|
||||||
|
paths for various compilers and platforms.
|
||||||
|
- [QTBUG-63197][Windows] Fixed moc'ing in a build directory with spaces
|
||||||
|
when INCLUDEPATH contains 40+ entries.
|
||||||
|
- [Android] Fixed building with ndkr16+ by using unified headers.
|
||||||
|
- [Windows] Fixed repeated installation of read-only files.
|
||||||
|
- [VS] Fixed deployment rules in created solution files.
|
Binary file not shown.
Before Width: | Height: | Size: 8.7 KiB After Width: | Height: | Size: 30 KiB |
Binary file not shown.
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 39 KiB |
@ -60,8 +60,8 @@
|
|||||||
the address book.
|
the address book.
|
||||||
|
|
||||||
\c TableModel is a subclass of QAbstractTableModel that provides
|
\c TableModel is a subclass of QAbstractTableModel that provides
|
||||||
the standard model/view API to access data. It also holds a
|
the standard model/view API to access data. It holds a list of
|
||||||
QList of \l{QPair}s corresponding to the contacts added.
|
added contacts.
|
||||||
However, this data is not all visible in a single tab. Instead,
|
However, this data is not all visible in a single tab. Instead,
|
||||||
QTableView is used to provide 9 different views of the same
|
QTableView is used to provide 9 different views of the same
|
||||||
data, according to the alphabet groups.
|
data, according to the alphabet groups.
|
||||||
@ -80,7 +80,7 @@
|
|||||||
\section1 TableModel Class Definition
|
\section1 TableModel Class Definition
|
||||||
|
|
||||||
The \c TableModel class provides standard API to access data in
|
The \c TableModel class provides standard API to access data in
|
||||||
its QList of \l{QPair}s by subclassing QAbstractTableModel. The
|
its list of contacts by subclassing QAbstractTableModel. The
|
||||||
basic functions that must be implemented in order to do so are:
|
basic functions that must be implemented in order to do so are:
|
||||||
\c rowCount(), \c columnCount(), \c data(), \c headerData().
|
\c rowCount(), \c columnCount(), \c data(), \c headerData().
|
||||||
For TableModel to be editable, it has to provide implementations
|
For TableModel to be editable, it has to provide implementations
|
||||||
@ -90,15 +90,14 @@
|
|||||||
\snippet itemviews/addressbook/tablemodel.h 0
|
\snippet itemviews/addressbook/tablemodel.h 0
|
||||||
|
|
||||||
Two constructors are used, a default constructor which uses
|
Two constructors are used, a default constructor which uses
|
||||||
\c TableModel's own \c {QList<QPair<QString, QString>>} and one
|
\c TableModel's own \c {QList<Contact>} and one that takes
|
||||||
that takes \c {QList<QPair<QString, QString>} as an argument,
|
\c {QList<Contact>} as an argument, for convenience.
|
||||||
for convenience.
|
|
||||||
|
|
||||||
|
|
||||||
\section1 TableModel Class Implementation
|
\section1 TableModel Class Implementation
|
||||||
|
|
||||||
We implement the two constructors as defined in the header file.
|
We implement the two constructors as defined in the header file.
|
||||||
The second constructor initializes the list of pairs in the
|
The second constructor initializes the list of contacts in the
|
||||||
model, with the parameter value.
|
model, with the parameter value.
|
||||||
|
|
||||||
\snippet itemviews/addressbook/tablemodel.cpp 0
|
\snippet itemviews/addressbook/tablemodel.cpp 0
|
||||||
@ -117,7 +116,7 @@
|
|||||||
The \c data() function returns either a \b Name or
|
The \c data() function returns either a \b Name or
|
||||||
\b {Address}, based on the contents of the model index
|
\b {Address}, based on the contents of the model index
|
||||||
supplied. The row number stored in the model index is used to
|
supplied. The row number stored in the model index is used to
|
||||||
reference an item in the list of pairs. Selection is handled
|
reference an item in the list of contacts. Selection is handled
|
||||||
by the QItemSelectionModel, which will be explained with
|
by the QItemSelectionModel, which will be explained with
|
||||||
\c AddressWidget.
|
\c AddressWidget.
|
||||||
|
|
||||||
@ -164,12 +163,11 @@
|
|||||||
use the editing features of the QTableView object, we enable
|
use the editing features of the QTableView object, we enable
|
||||||
them here so that we can reuse the model in other programs.
|
them here so that we can reuse the model in other programs.
|
||||||
|
|
||||||
The last function in \c {TableModel}, \c getList() returns the
|
The last function in \c {TableModel}, \c getContacts() returns the
|
||||||
QList<QPair<QString, QString>> object that holds all the
|
QList<Contact> object that holds all the contacts in the address
|
||||||
contacts in the address book. We use this function later to
|
book. We use this function later to obtain the list of contacts to
|
||||||
obtain the list of contacts to check for existing entries, write
|
check for existing entries, write the contacts to a file and read
|
||||||
the contacts to a file and read them back. Further explanation is
|
them back. Further explanation is given with \c AddressWidget.
|
||||||
given with \c AddressWidget.
|
|
||||||
|
|
||||||
\snippet itemviews/addressbook/tablemodel.cpp 8
|
\snippet itemviews/addressbook/tablemodel.cpp 8
|
||||||
|
|
||||||
@ -222,11 +220,12 @@
|
|||||||
The QItemSelectionModel class provides a
|
The QItemSelectionModel class provides a
|
||||||
\l{QItemSelectionModel::selectionChanged()}{selectionChanged}
|
\l{QItemSelectionModel::selectionChanged()}{selectionChanged}
|
||||||
signal that is connected to \c{AddressWidget}'s
|
signal that is connected to \c{AddressWidget}'s
|
||||||
\c selectionChanged() signal. This signal to signal connection
|
\c selectionChanged() signal. We also connect
|
||||||
is necessary to enable the \uicontrol{Edit Entry...} and
|
QTabWidget::currentChanged() signal to the lambda expression which
|
||||||
\uicontrol{Remove Entry} actions in \c MainWindow's Tools menu. This
|
emits \c{AddressWidget}'s \c selectionChanged() as well. These
|
||||||
connection is further explained in \c MainWindow's
|
connections are necessary to enable the \uicontrol{Edit Entry...} and
|
||||||
implementation.
|
\uicontrol{Remove Entry} actions in \c MainWindow's Tools menu.
|
||||||
|
It is further explained in \c MainWindow's implementation.
|
||||||
|
|
||||||
Each table view in the address book is added as a tab to the
|
Each table view in the address book is added as a tab to the
|
||||||
QTabWidget with the relevant label, obtained from the QStringList
|
QTabWidget with the relevant label, obtained from the QStringList
|
||||||
@ -250,7 +249,7 @@
|
|||||||
Basic validation is done in the second \c addEntry() function to
|
Basic validation is done in the second \c addEntry() function to
|
||||||
prevent duplicate entries in the address book. As mentioned with
|
prevent duplicate entries in the address book. As mentioned with
|
||||||
\c TableModel, this is part of the reason why we require the
|
\c TableModel, this is part of the reason why we require the
|
||||||
getter method \c getList().
|
getter method \c getContacts().
|
||||||
|
|
||||||
\snippet itemviews/addressbook/addresswidget.cpp 3
|
\snippet itemviews/addressbook/addresswidget.cpp 3
|
||||||
|
|
||||||
@ -292,7 +291,7 @@
|
|||||||
|
|
||||||
The \c writeToFile() function is used to save a file containing
|
The \c writeToFile() function is used to save a file containing
|
||||||
all the contacts in the address book. The file is saved in a
|
all the contacts in the address book. The file is saved in a
|
||||||
custom \c{.dat} format. The contents of the QList of \l{QPair}s
|
custom \c{.dat} format. The contents of the list of contacts
|
||||||
are written to \c file using QDataStream. If the file cannot be
|
are written to \c file using QDataStream. If the file cannot be
|
||||||
opened, a QMessageBox is displayed with the related error message.
|
opened, a QMessageBox is displayed with the related error message.
|
||||||
|
|
||||||
@ -301,7 +300,7 @@
|
|||||||
The \c readFromFile() function loads a file containing all the
|
The \c readFromFile() function loads a file containing all the
|
||||||
contacts in the address book, previously saved using
|
contacts in the address book, previously saved using
|
||||||
\c writeToFile(). QDataStream is used to read the contents of a
|
\c writeToFile(). QDataStream is used to read the contents of a
|
||||||
\c{.dat} file into a list of pairs and each of these is added
|
\c{.dat} file into a list of contacts and each of these is added
|
||||||
using \c addEntry().
|
using \c addEntry().
|
||||||
|
|
||||||
\snippet itemviews/addressbook/addresswidget.cpp 7
|
\snippet itemviews/addressbook/addresswidget.cpp 7
|
||||||
|
@ -62,7 +62,7 @@ QT_END_NAMESPACE
|
|||||||
class DragWidget : public QFrame
|
class DragWidget : public QFrame
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DragWidget(QWidget *parent = 0);
|
explicit DragWidget(QWidget *parent = nullptr);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void dragEnterEvent(QDragEnterEvent *event) override;
|
void dragEnterEvent(QDragEnterEvent *event) override;
|
||||||
|
@ -123,7 +123,7 @@ void DragWidget::dropEvent(QDropEvent *event)
|
|||||||
hotSpot.setY(hotSpotPos.last().toInt());
|
hotSpot.setY(hotSpotPos.last().toInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (const QString &piece, pieces) {
|
for (const QString &piece : pieces) {
|
||||||
QLabel *newLabel = createDragLabel(piece, this);
|
QLabel *newLabel = createDragLabel(piece, this);
|
||||||
newLabel->move(position - hotSpot);
|
newLabel->move(position - hotSpot);
|
||||||
newLabel->show();
|
newLabel->show();
|
||||||
@ -141,7 +141,7 @@ void DragWidget::dropEvent(QDropEvent *event)
|
|||||||
} else {
|
} else {
|
||||||
event->ignore();
|
event->ignore();
|
||||||
}
|
}
|
||||||
foreach (QWidget *widget, findChildren<QWidget *>()) {
|
for (QWidget *widget : findChildren<QWidget *>()) {
|
||||||
if (!widget->isVisible())
|
if (!widget->isVisible())
|
||||||
widget->deleteLater();
|
widget->deleteLater();
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,7 @@ QT_END_NAMESPACE
|
|||||||
class DragWidget : public QWidget
|
class DragWidget : public QWidget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DragWidget(QWidget *parent = 0);
|
explicit DragWidget(QWidget *parent = nullptr);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void dragEnterEvent(QDragEnterEvent *event) override;
|
void dragEnterEvent(QDragEnterEvent *event) override;
|
||||||
|
@ -63,13 +63,13 @@ class DropArea : public QLabel
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DropArea(QWidget *parent = 0);
|
explicit DropArea(QWidget *parent = nullptr);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void changed(const QMimeData *mimeData = 0);
|
void changed(const QMimeData *mimeData = nullptr);
|
||||||
//! [DropArea header part1]
|
//! [DropArea header part1]
|
||||||
|
|
||||||
//! [DropArea header part2]
|
//! [DropArea header part2]
|
||||||
|
@ -88,8 +88,8 @@ DropSiteWindow::DropSiteWindow()
|
|||||||
buttonBox->addButton(clearButton, QDialogButtonBox::ActionRole);
|
buttonBox->addButton(clearButton, QDialogButtonBox::ActionRole);
|
||||||
buttonBox->addButton(quitButton, QDialogButtonBox::RejectRole);
|
buttonBox->addButton(quitButton, QDialogButtonBox::RejectRole);
|
||||||
|
|
||||||
connect(quitButton, &QAbstractButton::pressed, this, &QWidget::close);
|
connect(quitButton, &QAbstractButton::clicked, this, &QWidget::close);
|
||||||
connect(clearButton, &QAbstractButton::pressed, dropArea, &DropArea::clear);
|
connect(clearButton, &QAbstractButton::clicked, dropArea, &DropArea::clear);
|
||||||
//! [constructor part4]
|
//! [constructor part4]
|
||||||
|
|
||||||
//! [constructor part5]
|
//! [constructor part5]
|
||||||
@ -113,7 +113,7 @@ void DropSiteWindow::updateFormatsTable(const QMimeData *mimeData)
|
|||||||
//! [updateFormatsTable() part1]
|
//! [updateFormatsTable() part1]
|
||||||
|
|
||||||
//! [updateFormatsTable() part2]
|
//! [updateFormatsTable() part2]
|
||||||
foreach (QString format, mimeData->formats()) {
|
for (const QString &format : mimeData->formats()) {
|
||||||
QTableWidgetItem *formatItem = new QTableWidgetItem(format);
|
QTableWidgetItem *formatItem = new QTableWidgetItem(format);
|
||||||
formatItem->setFlags(Qt::ItemIsEnabled);
|
formatItem->setFlags(Qt::ItemIsEnabled);
|
||||||
formatItem->setTextAlignment(Qt::AlignTop | Qt::AlignLeft);
|
formatItem->setTextAlignment(Qt::AlignTop | Qt::AlignLeft);
|
||||||
|
@ -167,7 +167,7 @@ void DragWidget::dropEvent(QDropEvent *event)
|
|||||||
QString::SkipEmptyParts);
|
QString::SkipEmptyParts);
|
||||||
QPoint position = event->pos();
|
QPoint position = event->pos();
|
||||||
|
|
||||||
foreach (const QString &piece, pieces) {
|
for (const QString &piece : pieces) {
|
||||||
DragLabel *newLabel = new DragLabel(piece, this);
|
DragLabel *newLabel = new DragLabel(piece, this);
|
||||||
newLabel->move(position);
|
newLabel->move(position);
|
||||||
newLabel->show();
|
newLabel->show();
|
||||||
|
@ -62,7 +62,7 @@ QT_END_NAMESPACE
|
|||||||
class DragWidget : public QWidget
|
class DragWidget : public QWidget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DragWidget(QWidget *parent = 0);
|
explicit DragWidget(QWidget *parent = nullptr);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void dragEnterEvent(QDragEnterEvent *event) override;
|
void dragEnterEvent(QDragEnterEvent *event) override;
|
||||||
|
@ -48,10 +48,10 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <QApplication>
|
|
||||||
|
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
Q_INIT_RESOURCE(puzzle);
|
Q_INIT_RESOURCE(puzzle);
|
||||||
|
@ -67,12 +67,19 @@ MainWindow::MainWindow(QWidget *parent)
|
|||||||
|
|
||||||
void MainWindow::openImage()
|
void MainWindow::openImage()
|
||||||
{
|
{
|
||||||
const QString fileName =
|
const QString directory =
|
||||||
QFileDialog::getOpenFileName(this, tr("Open Image"), QString(),
|
QStandardPaths::standardLocations(QStandardPaths::PicturesLocation).value(0, QDir::homePath());
|
||||||
tr("Image Files (*.png *.jpg *.bmp)"));
|
QFileDialog dialog(this, tr("Open Image"), directory);
|
||||||
|
dialog.setAcceptMode(QFileDialog::AcceptOpen);
|
||||||
if (!fileName.isEmpty())
|
dialog.setFileMode(QFileDialog::ExistingFile);
|
||||||
loadImage(fileName);
|
QStringList mimeTypeFilters;
|
||||||
|
for (const QByteArray &mimeTypeName : QImageReader::supportedMimeTypes())
|
||||||
|
mimeTypeFilters.append(mimeTypeName);
|
||||||
|
mimeTypeFilters.sort();
|
||||||
|
dialog.setMimeTypeFilters(mimeTypeFilters);
|
||||||
|
dialog.selectMimeTypeFilter("image/jpeg");
|
||||||
|
if (dialog.exec() == QDialog::Accepted)
|
||||||
|
loadImage(dialog.selectedFiles().constFirst());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::loadImage(const QString &fileName)
|
void MainWindow::loadImage(const QString &fileName)
|
||||||
|
@ -51,8 +51,8 @@
|
|||||||
#ifndef MAINWINDOW_H
|
#ifndef MAINWINDOW_H
|
||||||
#define MAINWINDOW_H
|
#define MAINWINDOW_H
|
||||||
|
|
||||||
#include <QPixmap>
|
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
|
#include <QPixmap>
|
||||||
|
|
||||||
class PiecesList;
|
class PiecesList;
|
||||||
class PuzzleWidget;
|
class PuzzleWidget;
|
||||||
@ -65,7 +65,7 @@ class MainWindow : public QMainWindow
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MainWindow(QWidget *parent = 0);
|
explicit MainWindow(QWidget *parent = nullptr);
|
||||||
void loadImage(const QString &path);
|
void loadImage(const QString &path);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
@ -101,7 +101,7 @@ void PiecesList::dropEvent(QDropEvent *event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PiecesList::addPiece(QPixmap pixmap, QPoint location)
|
void PiecesList::addPiece(const QPixmap &pixmap, const QPoint &location)
|
||||||
{
|
{
|
||||||
QListWidgetItem *pieceItem = new QListWidgetItem(this);
|
QListWidgetItem *pieceItem = new QListWidgetItem(this);
|
||||||
pieceItem->setIcon(QIcon(pixmap));
|
pieceItem->setIcon(QIcon(pixmap));
|
||||||
|
@ -58,8 +58,8 @@ class PiecesList : public QListWidget
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit PiecesList(int pieceSize, QWidget *parent = 0);
|
explicit PiecesList(int pieceSize, QWidget *parent = nullptr);
|
||||||
void addPiece(QPixmap pixmap, QPoint location);
|
void addPiece(const QPixmap &pixmap, const QPoint &location);
|
||||||
|
|
||||||
static QString puzzleMimeType() { return QStringLiteral("image/x-puzzle-piece"); }
|
static QString puzzleMimeType() { return QStringLiteral("image/x-puzzle-piece"); }
|
||||||
|
|
||||||
|
@ -66,9 +66,7 @@ PuzzleWidget::PuzzleWidget(int imageSize, QWidget *parent)
|
|||||||
|
|
||||||
void PuzzleWidget::clear()
|
void PuzzleWidget::clear()
|
||||||
{
|
{
|
||||||
pieceLocations.clear();
|
pieces.clear();
|
||||||
piecePixmaps.clear();
|
|
||||||
pieceRects.clear();
|
|
||||||
highlightedRect = QRect();
|
highlightedRect = QRect();
|
||||||
inPlace = 0;
|
inPlace = 0;
|
||||||
update();
|
update();
|
||||||
@ -95,7 +93,7 @@ void PuzzleWidget::dragMoveEvent(QDragMoveEvent *event)
|
|||||||
QRect updateRect = highlightedRect.united(targetSquare(event->pos()));
|
QRect updateRect = highlightedRect.united(targetSquare(event->pos()));
|
||||||
|
|
||||||
if (event->mimeData()->hasFormat(PiecesList::puzzleMimeType())
|
if (event->mimeData()->hasFormat(PiecesList::puzzleMimeType())
|
||||||
&& pieceRects.indexOf(targetSquare(event->pos())) == -1) {
|
&& findPiece(targetSquare(event->pos())) == -1) {
|
||||||
|
|
||||||
highlightedRect = targetSquare(event->pos());
|
highlightedRect = targetSquare(event->pos());
|
||||||
event->setDropAction(Qt::MoveAction);
|
event->setDropAction(Qt::MoveAction);
|
||||||
@ -111,26 +109,23 @@ void PuzzleWidget::dragMoveEvent(QDragMoveEvent *event)
|
|||||||
void PuzzleWidget::dropEvent(QDropEvent *event)
|
void PuzzleWidget::dropEvent(QDropEvent *event)
|
||||||
{
|
{
|
||||||
if (event->mimeData()->hasFormat(PiecesList::puzzleMimeType())
|
if (event->mimeData()->hasFormat(PiecesList::puzzleMimeType())
|
||||||
&& pieceRects.indexOf(targetSquare(event->pos())) == -1) {
|
&& findPiece(targetSquare(event->pos())) == -1) {
|
||||||
|
|
||||||
QByteArray pieceData = event->mimeData()->data(PiecesList::puzzleMimeType());
|
QByteArray pieceData = event->mimeData()->data(PiecesList::puzzleMimeType());
|
||||||
QDataStream dataStream(&pieceData, QIODevice::ReadOnly);
|
QDataStream dataStream(&pieceData, QIODevice::ReadOnly);
|
||||||
QRect square = targetSquare(event->pos());
|
Piece piece;
|
||||||
QPixmap pixmap;
|
piece.rect = targetSquare(event->pos());
|
||||||
QPoint location;
|
dataStream >> piece.pixmap >> piece.location;
|
||||||
dataStream >> pixmap >> location;
|
|
||||||
|
|
||||||
pieceLocations.append(location);
|
pieces.append(piece);
|
||||||
piecePixmaps.append(pixmap);
|
|
||||||
pieceRects.append(square);
|
|
||||||
|
|
||||||
highlightedRect = QRect();
|
highlightedRect = QRect();
|
||||||
update(square);
|
update(piece.rect);
|
||||||
|
|
||||||
event->setDropAction(Qt::MoveAction);
|
event->setDropAction(Qt::MoveAction);
|
||||||
event->accept();
|
event->accept();
|
||||||
|
|
||||||
if (location == QPoint(square.x()/pieceSize(), square.y()/pieceSize())) {
|
if (piece.location == piece.rect.topLeft() / pieceSize()) {
|
||||||
inPlace++;
|
inPlace++;
|
||||||
if (inPlace == 25)
|
if (inPlace == 25)
|
||||||
emit puzzleCompleted();
|
emit puzzleCompleted();
|
||||||
@ -141,21 +136,26 @@ void PuzzleWidget::dropEvent(QDropEvent *event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int PuzzleWidget::findPiece(const QRect &pieceRect) const
|
||||||
|
{
|
||||||
|
for (int i = 0, size = pieces.size(); i < size; ++i) {
|
||||||
|
if (pieces.at(i).rect == pieceRect)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
void PuzzleWidget::mousePressEvent(QMouseEvent *event)
|
void PuzzleWidget::mousePressEvent(QMouseEvent *event)
|
||||||
{
|
{
|
||||||
QRect square = targetSquare(event->pos());
|
QRect square = targetSquare(event->pos());
|
||||||
int found = pieceRects.indexOf(square);
|
const int found = findPiece(square);
|
||||||
|
|
||||||
if (found == -1)
|
if (found == -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QPoint location = pieceLocations[found];
|
Piece piece = pieces.takeAt(found);
|
||||||
QPixmap pixmap = piecePixmaps[found];
|
|
||||||
pieceLocations.removeAt(found);
|
|
||||||
piecePixmaps.removeAt(found);
|
|
||||||
pieceRects.removeAt(found);
|
|
||||||
|
|
||||||
if (location == QPoint(square.x()/pieceSize(), square.y()/pieceSize()))
|
if (piece.location == square.topLeft() / pieceSize())
|
||||||
inPlace--;
|
inPlace--;
|
||||||
|
|
||||||
update(square);
|
update(square);
|
||||||
@ -163,7 +163,7 @@ void PuzzleWidget::mousePressEvent(QMouseEvent *event)
|
|||||||
QByteArray itemData;
|
QByteArray itemData;
|
||||||
QDataStream dataStream(&itemData, QIODevice::WriteOnly);
|
QDataStream dataStream(&itemData, QIODevice::WriteOnly);
|
||||||
|
|
||||||
dataStream << pixmap << location;
|
dataStream << piece.pixmap << piece.location;
|
||||||
|
|
||||||
QMimeData *mimeData = new QMimeData;
|
QMimeData *mimeData = new QMimeData;
|
||||||
mimeData->setData(PiecesList::puzzleMimeType(), itemData);
|
mimeData->setData(PiecesList::puzzleMimeType(), itemData);
|
||||||
@ -171,23 +171,20 @@ void PuzzleWidget::mousePressEvent(QMouseEvent *event)
|
|||||||
QDrag *drag = new QDrag(this);
|
QDrag *drag = new QDrag(this);
|
||||||
drag->setMimeData(mimeData);
|
drag->setMimeData(mimeData);
|
||||||
drag->setHotSpot(event->pos() - square.topLeft());
|
drag->setHotSpot(event->pos() - square.topLeft());
|
||||||
drag->setPixmap(pixmap);
|
drag->setPixmap(piece.pixmap);
|
||||||
|
|
||||||
if (!(drag->exec(Qt::MoveAction) == Qt::MoveAction)) {
|
if (drag->exec(Qt::MoveAction) != Qt::MoveAction) {
|
||||||
pieceLocations.insert(found, location);
|
pieces.insert(found, piece);
|
||||||
piecePixmaps.insert(found, pixmap);
|
|
||||||
pieceRects.insert(found, square);
|
|
||||||
update(targetSquare(event->pos()));
|
update(targetSquare(event->pos()));
|
||||||
|
|
||||||
if (location == QPoint(square.x()/pieceSize(), square.y()/pieceSize()))
|
if (piece.location == square.topLeft() / pieceSize())
|
||||||
inPlace++;
|
inPlace++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PuzzleWidget::paintEvent(QPaintEvent *event)
|
void PuzzleWidget::paintEvent(QPaintEvent *event)
|
||||||
{
|
{
|
||||||
QPainter painter;
|
QPainter painter(this);
|
||||||
painter.begin(this);
|
|
||||||
painter.fillRect(event->rect(), Qt::white);
|
painter.fillRect(event->rect(), Qt::white);
|
||||||
|
|
||||||
if (highlightedRect.isValid()) {
|
if (highlightedRect.isValid()) {
|
||||||
@ -196,14 +193,14 @@ void PuzzleWidget::paintEvent(QPaintEvent *event)
|
|||||||
painter.drawRect(highlightedRect.adjusted(0, 0, -1, -1));
|
painter.drawRect(highlightedRect.adjusted(0, 0, -1, -1));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < pieceRects.size(); ++i)
|
for (const Piece &piece : pieces)
|
||||||
painter.drawPixmap(pieceRects[i], piecePixmaps[i]);
|
painter.drawPixmap(piece.rect, piece.pixmap);
|
||||||
painter.end();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const QRect PuzzleWidget::targetSquare(const QPoint &position) const
|
const QRect PuzzleWidget::targetSquare(const QPoint &position) const
|
||||||
{
|
{
|
||||||
return QRect(position.x()/pieceSize() * pieceSize(), position.y()/pieceSize() * pieceSize(), pieceSize(), pieceSize());
|
return QRect(position / pieceSize() * pieceSize(),
|
||||||
|
QSize(pieceSize(), pieceSize()));
|
||||||
}
|
}
|
||||||
|
|
||||||
int PuzzleWidget::pieceSize() const
|
int PuzzleWidget::pieceSize() const
|
||||||
|
@ -51,9 +51,9 @@
|
|||||||
#ifndef PUZZLEWIDGET_H
|
#ifndef PUZZLEWIDGET_H
|
||||||
#define PUZZLEWIDGET_H
|
#define PUZZLEWIDGET_H
|
||||||
|
|
||||||
#include <QList>
|
|
||||||
#include <QPoint>
|
#include <QPoint>
|
||||||
#include <QPixmap>
|
#include <QPixmap>
|
||||||
|
#include <QVector>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
@ -67,7 +67,7 @@ class PuzzleWidget : public QWidget
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit PuzzleWidget(int imageSize, QWidget *parent = 0);
|
explicit PuzzleWidget(int imageSize, QWidget *parent = nullptr);
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
int pieceSize() const;
|
int pieceSize() const;
|
||||||
@ -85,11 +85,16 @@ protected:
|
|||||||
void paintEvent(QPaintEvent *event) override;
|
void paintEvent(QPaintEvent *event) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
struct Piece {
|
||||||
|
QPixmap pixmap;
|
||||||
|
QRect rect;
|
||||||
|
QPoint location;
|
||||||
|
};
|
||||||
|
|
||||||
|
int findPiece(const QRect &pieceRect) const;
|
||||||
const QRect targetSquare(const QPoint &position) const;
|
const QRect targetSquare(const QPoint &position) const;
|
||||||
|
|
||||||
QList<QPixmap> piecePixmaps;
|
QVector<Piece> pieces;
|
||||||
QList<QRect> pieceRects;
|
|
||||||
QList<QPoint> pieceLocations;
|
|
||||||
QRect highlightedRect;
|
QRect highlightedRect;
|
||||||
int inPlace;
|
int inPlace;
|
||||||
int m_ImageSize;
|
int m_ImageSize;
|
||||||
|
@ -85,10 +85,7 @@ void AddressWidget::showAddEntryDialog()
|
|||||||
//! [3]
|
//! [3]
|
||||||
void AddressWidget::addEntry(QString name, QString address)
|
void AddressWidget::addEntry(QString name, QString address)
|
||||||
{
|
{
|
||||||
QList<QPair<QString, QString> >list = table->getList();
|
if (!table->getContacts().contains({ name, address })) {
|
||||||
QPair<QString, QString> pair(name, address);
|
|
||||||
|
|
||||||
if (!list.contains(pair)) {
|
|
||||||
table->insertRows(0, 1, QModelIndex());
|
table->insertRows(0, 1, QModelIndex());
|
||||||
|
|
||||||
QModelIndex index = table->index(0, 0, QModelIndex());
|
QModelIndex index = table->index(0, 0, QModelIndex());
|
||||||
@ -195,6 +192,12 @@ void AddressWidget::setupTabs()
|
|||||||
&QItemSelectionModel::selectionChanged,
|
&QItemSelectionModel::selectionChanged,
|
||||||
this, &AddressWidget::selectionChanged);
|
this, &AddressWidget::selectionChanged);
|
||||||
|
|
||||||
|
connect(this, &QTabWidget::currentChanged, this, [this](int tabIndex) {
|
||||||
|
auto *tableView = qobject_cast<QTableView *>(widget(tabIndex));
|
||||||
|
if (tableView)
|
||||||
|
emit selectionChanged(tableView->selectionModel()->selection());
|
||||||
|
});
|
||||||
|
|
||||||
addTab(tableView, str);
|
addTab(tableView, str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -211,18 +214,16 @@ void AddressWidget::readFromFile(const QString &fileName)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QPair<QString, QString> > pairs = table->getList();
|
QList<Contact> contacts;
|
||||||
QDataStream in(&file);
|
QDataStream in(&file);
|
||||||
in >> pairs;
|
in >> contacts;
|
||||||
|
|
||||||
if (pairs.isEmpty()) {
|
if (contacts.isEmpty()) {
|
||||||
QMessageBox::information(this, tr("No contacts in file"),
|
QMessageBox::information(this, tr("No contacts in file"),
|
||||||
tr("The file you are attempting to open contains no contacts."));
|
tr("The file you are attempting to open contains no contacts."));
|
||||||
} else {
|
} else {
|
||||||
for (int i=0; i<pairs.size(); ++i) {
|
for (const auto &contact: qAsConst(contacts))
|
||||||
QPair<QString, QString> p = pairs.at(i);
|
addEntry(contact.name, contact.address);
|
||||||
addEntry(p.first, p.second);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//! [7]
|
//! [7]
|
||||||
@ -237,8 +238,7 @@ void AddressWidget::writeToFile(const QString &fileName)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QPair<QString, QString> > pairs = table->getList();
|
|
||||||
QDataStream out(&file);
|
QDataStream out(&file);
|
||||||
out << pairs;
|
out << table->getContacts();
|
||||||
}
|
}
|
||||||
//! [6]
|
//! [6]
|
||||||
|
@ -56,10 +56,10 @@ TableModel::TableModel(QObject *parent)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
TableModel::TableModel(QList<QPair<QString, QString> > pairs, QObject *parent)
|
TableModel::TableModel(QList<Contact> contacts, QObject *parent)
|
||||||
: QAbstractTableModel(parent)
|
: QAbstractTableModel(parent)
|
||||||
|
, contacts(contacts)
|
||||||
{
|
{
|
||||||
listOfPairs = pairs;
|
|
||||||
}
|
}
|
||||||
//! [0]
|
//! [0]
|
||||||
|
|
||||||
@ -67,7 +67,7 @@ TableModel::TableModel(QList<QPair<QString, QString> > pairs, QObject *parent)
|
|||||||
int TableModel::rowCount(const QModelIndex &parent) const
|
int TableModel::rowCount(const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
Q_UNUSED(parent);
|
Q_UNUSED(parent);
|
||||||
return listOfPairs.size();
|
return contacts.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
int TableModel::columnCount(const QModelIndex &parent) const
|
int TableModel::columnCount(const QModelIndex &parent) const
|
||||||
@ -83,16 +83,16 @@ QVariant TableModel::data(const QModelIndex &index, int role) const
|
|||||||
if (!index.isValid())
|
if (!index.isValid())
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
|
||||||
if (index.row() >= listOfPairs.size() || index.row() < 0)
|
if (index.row() >= contacts.size() || index.row() < 0)
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
|
||||||
if (role == Qt::DisplayRole) {
|
if (role == Qt::DisplayRole) {
|
||||||
QPair<QString, QString> pair = listOfPairs.at(index.row());
|
const auto &contact = contacts.at(index.row());
|
||||||
|
|
||||||
if (index.column() == 0)
|
if (index.column() == 0)
|
||||||
return pair.first;
|
return contact.name;
|
||||||
else if (index.column() == 1)
|
else if (index.column() == 1)
|
||||||
return pair.second;
|
return contact.address;
|
||||||
}
|
}
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
@ -126,10 +126,8 @@ bool TableModel::insertRows(int position, int rows, const QModelIndex &index)
|
|||||||
Q_UNUSED(index);
|
Q_UNUSED(index);
|
||||||
beginInsertRows(QModelIndex(), position, position + rows - 1);
|
beginInsertRows(QModelIndex(), position, position + rows - 1);
|
||||||
|
|
||||||
for (int row = 0; row < rows; ++row) {
|
for (int row = 0; row < rows; ++row)
|
||||||
QPair<QString, QString> pair(" ", " ");
|
contacts.insert(position, { QString(), QString() });
|
||||||
listOfPairs.insert(position, pair);
|
|
||||||
}
|
|
||||||
|
|
||||||
endInsertRows();
|
endInsertRows();
|
||||||
return true;
|
return true;
|
||||||
@ -142,9 +140,8 @@ bool TableModel::removeRows(int position, int rows, const QModelIndex &index)
|
|||||||
Q_UNUSED(index);
|
Q_UNUSED(index);
|
||||||
beginRemoveRows(QModelIndex(), position, position + rows - 1);
|
beginRemoveRows(QModelIndex(), position, position + rows - 1);
|
||||||
|
|
||||||
for (int row = 0; row < rows; ++row) {
|
for (int row = 0; row < rows; ++row)
|
||||||
listOfPairs.removeAt(position);
|
contacts.removeAt(position);
|
||||||
}
|
|
||||||
|
|
||||||
endRemoveRows();
|
endRemoveRows();
|
||||||
return true;
|
return true;
|
||||||
@ -157,16 +154,16 @@ bool TableModel::setData(const QModelIndex &index, const QVariant &value, int ro
|
|||||||
if (index.isValid() && role == Qt::EditRole) {
|
if (index.isValid() && role == Qt::EditRole) {
|
||||||
int row = index.row();
|
int row = index.row();
|
||||||
|
|
||||||
QPair<QString, QString> p = listOfPairs.value(row);
|
auto contact = contacts.value(row);
|
||||||
|
|
||||||
if (index.column() == 0)
|
if (index.column() == 0)
|
||||||
p.first = value.toString();
|
contact.name = value.toString();
|
||||||
else if (index.column() == 1)
|
else if (index.column() == 1)
|
||||||
p.second = value.toString();
|
contact.address = value.toString();
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
listOfPairs.replace(row, p);
|
contacts.replace(row, contact);
|
||||||
emit(dataChanged(index, index));
|
emit(dataChanged(index, index));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -187,8 +184,8 @@ Qt::ItemFlags TableModel::flags(const QModelIndex &index) const
|
|||||||
//! [7]
|
//! [7]
|
||||||
|
|
||||||
//! [8]
|
//! [8]
|
||||||
QList< QPair<QString, QString> > TableModel::getList()
|
QList<Contact> TableModel::getContacts() const
|
||||||
{
|
{
|
||||||
return listOfPairs;
|
return contacts;
|
||||||
}
|
}
|
||||||
//! [8]
|
//! [8]
|
||||||
|
@ -53,16 +53,37 @@
|
|||||||
|
|
||||||
#include <QAbstractTableModel>
|
#include <QAbstractTableModel>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QPair>
|
|
||||||
|
|
||||||
//! [0]
|
//! [0]
|
||||||
|
|
||||||
|
struct Contact
|
||||||
|
{
|
||||||
|
QString name;
|
||||||
|
QString address;
|
||||||
|
|
||||||
|
bool operator==(const Contact &other) const
|
||||||
|
{
|
||||||
|
return name == other.name && address == other.address;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
inline QDataStream &operator<<(QDataStream &stream, const Contact &contact)
|
||||||
|
{
|
||||||
|
return stream << contact.name << contact.address;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline QDataStream &operator>>(QDataStream &stream, Contact &contact)
|
||||||
|
{
|
||||||
|
return stream >> contact.name >> contact.address;
|
||||||
|
}
|
||||||
|
|
||||||
class TableModel : public QAbstractTableModel
|
class TableModel : public QAbstractTableModel
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TableModel(QObject *parent = 0);
|
TableModel(QObject *parent = 0);
|
||||||
TableModel(QList<QPair<QString, QString> > listofPairs, QObject *parent = 0);
|
TableModel(QList<Contact> contacts, QObject *parent = 0);
|
||||||
|
|
||||||
int rowCount(const QModelIndex &parent) const override;
|
int rowCount(const QModelIndex &parent) const override;
|
||||||
int columnCount(const QModelIndex &parent) const override;
|
int columnCount(const QModelIndex &parent) const override;
|
||||||
@ -72,10 +93,10 @@ public:
|
|||||||
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
|
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
|
||||||
bool insertRows(int position, int rows, const QModelIndex &index = QModelIndex()) override;
|
bool insertRows(int position, int rows, const QModelIndex &index = QModelIndex()) override;
|
||||||
bool removeRows(int position, int rows, const QModelIndex &index = QModelIndex()) override;
|
bool removeRows(int position, int rows, const QModelIndex &index = QModelIndex()) override;
|
||||||
QList<QPair<QString, QString> > getList();
|
QList<Contact> getContacts() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QList<QPair<QString, QString> > listOfPairs;
|
QList<Contact> contacts;
|
||||||
};
|
};
|
||||||
//! [0]
|
//! [0]
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
QApplication app(argc, argv);
|
QApplication app(argc, argv);
|
||||||
MainWindow window;
|
MainWindow window;
|
||||||
window.loadImage(":/images/example.jpg");
|
window.loadImage(QStringLiteral(":/images/example.jpg"));
|
||||||
window.show();
|
window.show();
|
||||||
return app.exec();
|
return app.exec();
|
||||||
}
|
}
|
||||||
|
@ -69,12 +69,19 @@ MainWindow::MainWindow(QWidget *parent)
|
|||||||
|
|
||||||
void MainWindow::openImage()
|
void MainWindow::openImage()
|
||||||
{
|
{
|
||||||
const QString fileName =
|
const QString directory =
|
||||||
QFileDialog::getOpenFileName(this,
|
QStandardPaths::standardLocations(QStandardPaths::PicturesLocation).value(0, QDir::homePath());
|
||||||
tr("Open Image"), QString(),
|
QFileDialog dialog(this, tr("Open Image"), directory);
|
||||||
tr("Image Files (*.png *.jpg *.bmp)"));
|
dialog.setAcceptMode(QFileDialog::AcceptOpen);
|
||||||
if (!fileName.isEmpty())
|
dialog.setFileMode(QFileDialog::ExistingFile);
|
||||||
loadImage(fileName);
|
QStringList mimeTypeFilters;
|
||||||
|
for (const QByteArray &mimeTypeName : QImageReader::supportedMimeTypes())
|
||||||
|
mimeTypeFilters.append(mimeTypeName);
|
||||||
|
mimeTypeFilters.sort();
|
||||||
|
dialog.setMimeTypeFilters(mimeTypeFilters);
|
||||||
|
dialog.selectMimeTypeFilter("image/jpeg");
|
||||||
|
if (dialog.exec() == QDialog::Accepted)
|
||||||
|
loadImage(dialog.selectedFiles().constFirst());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::loadImage(const QString &fileName)
|
void MainWindow::loadImage(const QString &fileName)
|
||||||
@ -83,7 +90,7 @@ void MainWindow::loadImage(const QString &fileName)
|
|||||||
if (!newImage.load(fileName)) {
|
if (!newImage.load(fileName)) {
|
||||||
QMessageBox::warning(this, tr("Open Image"),
|
QMessageBox::warning(this, tr("Open Image"),
|
||||||
tr("The image file could not be loaded."),
|
tr("The image file could not be loaded."),
|
||||||
QMessageBox::Cancel);
|
QMessageBox::Close);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
puzzleImage = newImage;
|
puzzleImage = newImage;
|
||||||
@ -117,19 +124,15 @@ void MainWindow::setupMenus()
|
|||||||
{
|
{
|
||||||
QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
|
QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
|
||||||
|
|
||||||
QAction *openAction = fileMenu->addAction(tr("&Open..."));
|
QAction *openAction = fileMenu->addAction(tr("&Open..."), this, &MainWindow::openImage);
|
||||||
openAction->setShortcuts(QKeySequence::Open);
|
openAction->setShortcuts(QKeySequence::Open);
|
||||||
|
|
||||||
QAction *exitAction = fileMenu->addAction(tr("E&xit"));
|
QAction *exitAction = fileMenu->addAction(tr("E&xit"), qApp, &QCoreApplication::quit);
|
||||||
exitAction->setShortcuts(QKeySequence::Quit);
|
exitAction->setShortcuts(QKeySequence::Quit);
|
||||||
|
|
||||||
QMenu *gameMenu = menuBar()->addMenu(tr("&Game"));
|
QMenu *gameMenu = menuBar()->addMenu(tr("&Game"));
|
||||||
|
|
||||||
QAction *restartAction = gameMenu->addAction(tr("&Restart"));
|
gameMenu->addAction(tr("&Restart"), this, &MainWindow::setupPuzzle);
|
||||||
|
|
||||||
connect(openAction, &QAction::triggered, this, &MainWindow::openImage);
|
|
||||||
connect(exitAction, &QAction::triggered, qApp, &QCoreApplication::quit);
|
|
||||||
connect(restartAction, &QAction::triggered, this, &MainWindow::setupPuzzle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::setupWidgets()
|
void MainWindow::setupWidgets()
|
||||||
|
@ -65,7 +65,7 @@ class MainWindow : public QMainWindow
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MainWindow(QWidget *parent = 0);
|
explicit MainWindow(QWidget *parent = nullptr);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void openImage();
|
void openImage();
|
||||||
|
@ -62,9 +62,7 @@ PuzzleWidget::PuzzleWidget(int imageSize, QWidget *parent)
|
|||||||
|
|
||||||
void PuzzleWidget::clear()
|
void PuzzleWidget::clear()
|
||||||
{
|
{
|
||||||
pieceLocations.clear();
|
pieces.clear();
|
||||||
piecePixmaps.clear();
|
|
||||||
pieceRects.clear();
|
|
||||||
highlightedRect = QRect();
|
highlightedRect = QRect();
|
||||||
inPlace = 0;
|
inPlace = 0;
|
||||||
update();
|
update();
|
||||||
@ -110,23 +108,20 @@ void PuzzleWidget::dropEvent(QDropEvent *event)
|
|||||||
&& findPiece(targetSquare(event->pos())) == -1) {
|
&& findPiece(targetSquare(event->pos())) == -1) {
|
||||||
|
|
||||||
QByteArray pieceData = event->mimeData()->data("image/x-puzzle-piece");
|
QByteArray pieceData = event->mimeData()->data("image/x-puzzle-piece");
|
||||||
QDataStream stream(&pieceData, QIODevice::ReadOnly);
|
QDataStream dataStream(&pieceData, QIODevice::ReadOnly);
|
||||||
QRect square = targetSquare(event->pos());
|
Piece piece;
|
||||||
QPixmap pixmap;
|
piece.rect = targetSquare(event->pos());
|
||||||
QPoint location;
|
dataStream >> piece.pixmap >> piece.location;
|
||||||
stream >> pixmap >> location;
|
|
||||||
|
|
||||||
pieceLocations.append(location);
|
pieces.append(piece);
|
||||||
piecePixmaps.append(pixmap);
|
|
||||||
pieceRects.append(square);
|
|
||||||
|
|
||||||
highlightedRect = QRect();
|
highlightedRect = QRect();
|
||||||
update(square);
|
update(piece.rect);
|
||||||
|
|
||||||
event->setDropAction(Qt::MoveAction);
|
event->setDropAction(Qt::MoveAction);
|
||||||
event->accept();
|
event->accept();
|
||||||
|
|
||||||
if (location == QPoint(square.x()/pieceSize(), square.y()/pieceSize())) {
|
if (piece.location == piece.rect.topLeft() / pieceSize()) {
|
||||||
inPlace++;
|
inPlace++;
|
||||||
if (inPlace == 25)
|
if (inPlace == 25)
|
||||||
emit puzzleCompleted();
|
emit puzzleCompleted();
|
||||||
@ -139,8 +134,8 @@ void PuzzleWidget::dropEvent(QDropEvent *event)
|
|||||||
|
|
||||||
int PuzzleWidget::findPiece(const QRect &pieceRect) const
|
int PuzzleWidget::findPiece(const QRect &pieceRect) const
|
||||||
{
|
{
|
||||||
for (int i = 0; i < pieceRects.size(); ++i) {
|
for (int i = 0, size = pieces.size(); i < size; ++i) {
|
||||||
if (pieceRect == pieceRects[i])
|
if (pieces.at(i).rect == pieceRect)
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
@ -154,13 +149,9 @@ void PuzzleWidget::mousePressEvent(QMouseEvent *event)
|
|||||||
if (found == -1)
|
if (found == -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QPoint location = pieceLocations[found];
|
Piece piece = pieces.takeAt(found);
|
||||||
QPixmap pixmap = piecePixmaps[found];
|
|
||||||
pieceLocations.removeAt(found);
|
|
||||||
piecePixmaps.removeAt(found);
|
|
||||||
pieceRects.removeAt(found);
|
|
||||||
|
|
||||||
if (location == QPoint(square.x()/pieceSize(), square.y()/pieceSize()))
|
if (piece.location == square.topLeft() / pieceSize())
|
||||||
inPlace--;
|
inPlace--;
|
||||||
|
|
||||||
update(square);
|
update(square);
|
||||||
@ -168,7 +159,7 @@ void PuzzleWidget::mousePressEvent(QMouseEvent *event)
|
|||||||
QByteArray itemData;
|
QByteArray itemData;
|
||||||
QDataStream dataStream(&itemData, QIODevice::WriteOnly);
|
QDataStream dataStream(&itemData, QIODevice::WriteOnly);
|
||||||
|
|
||||||
dataStream << pixmap << location;
|
dataStream << piece.pixmap << piece.location;
|
||||||
|
|
||||||
QMimeData *mimeData = new QMimeData;
|
QMimeData *mimeData = new QMimeData;
|
||||||
mimeData->setData("image/x-puzzle-piece", itemData);
|
mimeData->setData("image/x-puzzle-piece", itemData);
|
||||||
@ -176,23 +167,20 @@ void PuzzleWidget::mousePressEvent(QMouseEvent *event)
|
|||||||
QDrag *drag = new QDrag(this);
|
QDrag *drag = new QDrag(this);
|
||||||
drag->setMimeData(mimeData);
|
drag->setMimeData(mimeData);
|
||||||
drag->setHotSpot(event->pos() - square.topLeft());
|
drag->setHotSpot(event->pos() - square.topLeft());
|
||||||
drag->setPixmap(pixmap);
|
drag->setPixmap(piece.pixmap);
|
||||||
|
|
||||||
if (drag->start(Qt::MoveAction) == 0) {
|
if (drag->start(Qt::MoveAction) == Qt::IgnoreAction) {
|
||||||
pieceLocations.insert(found, location);
|
pieces.insert(found, piece);
|
||||||
piecePixmaps.insert(found, pixmap);
|
|
||||||
pieceRects.insert(found, square);
|
|
||||||
update(targetSquare(event->pos()));
|
update(targetSquare(event->pos()));
|
||||||
|
|
||||||
if (location == QPoint(square.x()/pieceSize(), square.y()/pieceSize()))
|
if (piece.location == QPoint(square.x() / pieceSize(), square.y() / pieceSize()))
|
||||||
inPlace++;
|
inPlace++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PuzzleWidget::paintEvent(QPaintEvent *event)
|
void PuzzleWidget::paintEvent(QPaintEvent *event)
|
||||||
{
|
{
|
||||||
QPainter painter;
|
QPainter painter(this);
|
||||||
painter.begin(this);
|
|
||||||
painter.fillRect(event->rect(), Qt::white);
|
painter.fillRect(event->rect(), Qt::white);
|
||||||
|
|
||||||
if (highlightedRect.isValid()) {
|
if (highlightedRect.isValid()) {
|
||||||
@ -201,15 +189,14 @@ void PuzzleWidget::paintEvent(QPaintEvent *event)
|
|||||||
painter.drawRect(highlightedRect.adjusted(0, 0, -1, -1));
|
painter.drawRect(highlightedRect.adjusted(0, 0, -1, -1));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < pieceRects.size(); ++i) {
|
for (const Piece &piece : pieces)
|
||||||
painter.drawPixmap(pieceRects[i], piecePixmaps[i]);
|
painter.drawPixmap(piece.rect, piece.pixmap);
|
||||||
}
|
|
||||||
painter.end();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const QRect PuzzleWidget::targetSquare(const QPoint &position) const
|
const QRect PuzzleWidget::targetSquare(const QPoint &position) const
|
||||||
{
|
{
|
||||||
return QRect(position.x()/pieceSize() * pieceSize(), position.y()/pieceSize() * pieceSize(), pieceSize(), pieceSize());
|
return QRect(position / pieceSize() * pieceSize(),
|
||||||
|
QSize(pieceSize(), pieceSize()));
|
||||||
}
|
}
|
||||||
|
|
||||||
int PuzzleWidget::pieceSize() const
|
int PuzzleWidget::pieceSize() const
|
||||||
|
@ -51,9 +51,9 @@
|
|||||||
#ifndef PUZZLEWIDGET_H
|
#ifndef PUZZLEWIDGET_H
|
||||||
#define PUZZLEWIDGET_H
|
#define PUZZLEWIDGET_H
|
||||||
|
|
||||||
#include <QList>
|
|
||||||
#include <QPixmap>
|
|
||||||
#include <QPoint>
|
#include <QPoint>
|
||||||
|
#include <QPixmap>
|
||||||
|
#include <QVector>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
@ -67,7 +67,7 @@ class PuzzleWidget : public QWidget
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit PuzzleWidget(int imageSize, QWidget *parent = 0);
|
explicit PuzzleWidget(int imageSize, QWidget *parent = nullptr);
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
int pieceSize() const;
|
int pieceSize() const;
|
||||||
@ -85,12 +85,16 @@ protected:
|
|||||||
void paintEvent(QPaintEvent *event) override;
|
void paintEvent(QPaintEvent *event) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
struct Piece {
|
||||||
|
QPixmap pixmap;
|
||||||
|
QRect rect;
|
||||||
|
QPoint location;
|
||||||
|
};
|
||||||
|
|
||||||
int findPiece(const QRect &pieceRect) const;
|
int findPiece(const QRect &pieceRect) const;
|
||||||
const QRect targetSquare(const QPoint &position) const;
|
const QRect targetSquare(const QPoint &position) const;
|
||||||
|
|
||||||
QList<QPixmap> piecePixmaps;
|
QVector<Piece> pieces;
|
||||||
QList<QRect> pieceRects;
|
|
||||||
QList<QPoint> pieceLocations;
|
|
||||||
QRect highlightedRect;
|
QRect highlightedRect;
|
||||||
int inPlace;
|
int inPlace;
|
||||||
int m_ImageSize;
|
int m_ImageSize;
|
||||||
|
@ -129,6 +129,10 @@ PatternLineEdit::PatternLineEdit(QWidget *parent) :
|
|||||||
connect(escapeSelectionAction, &QAction::triggered, this, &PatternLineEdit::escapeSelection);
|
connect(escapeSelectionAction, &QAction::triggered, this, &PatternLineEdit::escapeSelection);
|
||||||
connect(copyToCodeAction, &QAction::triggered, this, &PatternLineEdit::copyToCode);
|
connect(copyToCodeAction, &QAction::triggered, this, &PatternLineEdit::copyToCode);
|
||||||
connect(pasteFromCodeAction, &QAction::triggered, this, &PatternLineEdit::pasteFromCode);
|
connect(pasteFromCodeAction, &QAction::triggered, this, &PatternLineEdit::pasteFromCode);
|
||||||
|
#if !QT_CONFIG(clipboard)
|
||||||
|
copyToCodeAction->setEnabled(false);
|
||||||
|
pasteFromCodeAction->setEnabled(false);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void PatternLineEdit::escapeSelection()
|
void PatternLineEdit::escapeSelection()
|
||||||
@ -144,12 +148,16 @@ void PatternLineEdit::escapeSelection()
|
|||||||
|
|
||||||
void PatternLineEdit::copyToCode()
|
void PatternLineEdit::copyToCode()
|
||||||
{
|
{
|
||||||
|
#if QT_CONFIG(clipboard)
|
||||||
QGuiApplication::clipboard()->setText(patternToCode(text()));
|
QGuiApplication::clipboard()->setText(patternToCode(text()));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void PatternLineEdit::pasteFromCode()
|
void PatternLineEdit::pasteFromCode()
|
||||||
{
|
{
|
||||||
|
#if QT_CONFIG(clipboard)
|
||||||
setText(codeToPattern(QGuiApplication::clipboard()->text()));
|
setText(codeToPattern(QGuiApplication::clipboard()->text()));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void PatternLineEdit::contextMenuEvent(QContextMenuEvent *event)
|
void PatternLineEdit::contextMenuEvent(QContextMenuEvent *event)
|
||||||
@ -316,7 +324,7 @@ void RegularExpressionDialog::refresh()
|
|||||||
|
|
||||||
void RegularExpressionDialog::copyEscapedPatternToClipboard()
|
void RegularExpressionDialog::copyEscapedPatternToClipboard()
|
||||||
{
|
{
|
||||||
#ifndef QT_NO_CLIPBOARD
|
#if QT_CONFIG(clipboard)
|
||||||
QClipboard *clipboard = QGuiApplication::clipboard();
|
QClipboard *clipboard = QGuiApplication::clipboard();
|
||||||
if (clipboard)
|
if (clipboard)
|
||||||
clipboard->setText(escapedPatternLineEdit->text());
|
clipboard->setText(escapedPatternLineEdit->text());
|
||||||
@ -361,7 +369,7 @@ QWidget *RegularExpressionDialog::setupLeftUi()
|
|||||||
palette.setBrush(QPalette::Base, palette.brush(QPalette::Disabled, QPalette::Base));
|
palette.setBrush(QPalette::Base, palette.brush(QPalette::Disabled, QPalette::Base));
|
||||||
escapedPatternLineEdit->setPalette(palette);
|
escapedPatternLineEdit->setPalette(palette);
|
||||||
|
|
||||||
#ifndef QT_NO_CLIPBOARD
|
#if QT_CONFIG(clipboard)
|
||||||
QAction *copyEscapedPatternAction = new QAction(this);
|
QAction *copyEscapedPatternAction = new QAction(this);
|
||||||
copyEscapedPatternAction->setText(tr("Copy to clipboard"));
|
copyEscapedPatternAction->setText(tr("Copy to clipboard"));
|
||||||
copyEscapedPatternAction->setIcon(QIcon(QStringLiteral(":/images/copy.png")));
|
copyEscapedPatternAction->setIcon(QIcon(QStringLiteral(":/images/copy.png")));
|
||||||
|
@ -1,10 +1,5 @@
|
|||||||
|
|
||||||
win32 {
|
cmake_version_output = $$system(cmake --version 2>$$QMAKE_SYSTEM_NULL_DEVICE, lines)
|
||||||
cmake_version_output = $$system(cmake --version 2>NUL, lines)
|
|
||||||
} else {
|
|
||||||
cmake_version_output = $$system(cmake --version 2>/dev/null, lines)
|
|
||||||
}
|
|
||||||
|
|
||||||
# First line
|
# First line
|
||||||
cmake_version_output = $$first(cmake_version_output)
|
cmake_version_output = $$first(cmake_version_output)
|
||||||
# Format is "cmake version X.Y.Z"
|
# Format is "cmake version X.Y.Z"
|
||||||
@ -19,12 +14,7 @@ isEmpty(CMAKE_VERSION) {
|
|||||||
return()
|
return()
|
||||||
}
|
}
|
||||||
|
|
||||||
win32 {
|
CTEST_VERSION = $$system(ctest --version 2>$$QMAKE_SYSTEM_NULL_DEVICE)
|
||||||
CTEST_VERSION = $$system(ctest --version 2>NUL)
|
|
||||||
} else {
|
|
||||||
CTEST_VERSION = $$system(ctest --version 2>/dev/null)
|
|
||||||
}
|
|
||||||
|
|
||||||
isEmpty(CTEST_VERSION) {
|
isEmpty(CTEST_VERSION) {
|
||||||
message("ctest executable not found. Not running CMake unit tests")
|
message("ctest executable not found. Not running CMake unit tests")
|
||||||
return()
|
return()
|
||||||
|
@ -13,5 +13,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
$$add_plist: \
|
$$add_plist: \
|
||||||
QMAKE_LFLAGS += -Wl,-sectcreate,__TEXT,__info_plist,$$shell_quote($$QMAKE_INFO_PLIST)
|
QMAKE_LFLAGS += -Wl,-sectcreate,__TEXT,__info_plist,$$shell_quote( \
|
||||||
|
$$relative_path($$absolute_path($$QMAKE_INFO_PLIST, $$_PRO_FILE_PWD_), $$OUT_PWD))
|
||||||
}
|
}
|
||||||
|
@ -100,6 +100,9 @@ unix: CONFIG += explicitlib
|
|||||||
# By default we want tests on macOS to be built as standalone executables
|
# By default we want tests on macOS to be built as standalone executables
|
||||||
macos: CONFIG += testcase_no_bundle
|
macos: CONFIG += testcase_no_bundle
|
||||||
|
|
||||||
|
# Override MinGW's definition in _mingw.h
|
||||||
|
mingw: DEFINES += WINVER=0x0601 _WIN32_WINNT=0x0601
|
||||||
|
|
||||||
defineTest(qtBuildPart) {
|
defineTest(qtBuildPart) {
|
||||||
bp = $$eval($$upper($$section(_QMAKE_CONF_, /, -2, -2))_BUILD_PARTS)
|
bp = $$eval($$upper($$section(_QMAKE_CONF_, /, -2, -2))_BUILD_PARTS)
|
||||||
isEmpty(bp): bp = $$QT_BUILD_PARTS
|
isEmpty(bp): bp = $$QT_BUILD_PARTS
|
||||||
|
@ -291,10 +291,7 @@ defineReplace(pkgConfigExecutable) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
equals(QMAKE_HOST.os, Windows): \
|
PKG_CONFIG += 2> $$QMAKE_SYSTEM_NULL_DEVICE
|
||||||
PKG_CONFIG += 2> NUL
|
|
||||||
else: \
|
|
||||||
PKG_CONFIG += 2> /dev/null
|
|
||||||
|
|
||||||
return($$PKG_CONFIG)
|
return($$PKG_CONFIG)
|
||||||
}
|
}
|
||||||
|
@ -82,6 +82,7 @@ equals(MAKEFILE_GENERATOR, MSBUILD) \
|
|||||||
QMAKE_MKDIR = mkdir # legacy
|
QMAKE_MKDIR = mkdir # legacy
|
||||||
QMAKE_MKDIR_CMD = if not exist %1 mkdir %1 & if not exist %1 exit 1
|
QMAKE_MKDIR_CMD = if not exist %1 mkdir %1 & if not exist %1 exit 1
|
||||||
QMAKE_STREAM_EDITOR = $(QMAKE) -install sed
|
QMAKE_STREAM_EDITOR = $(QMAKE) -install sed
|
||||||
|
QMAKE_SHELL_NULL_DEVICE = NUL
|
||||||
QMAKE_INSTALL_FILE = copy /y
|
QMAKE_INSTALL_FILE = copy /y
|
||||||
QMAKE_INSTALL_PROGRAM = copy /y
|
QMAKE_INSTALL_PROGRAM = copy /y
|
||||||
} else {
|
} else {
|
||||||
@ -101,6 +102,7 @@ equals(MAKEFILE_GENERATOR, MSBUILD) \
|
|||||||
QMAKE_MKDIR = mkdir -p # legacy
|
QMAKE_MKDIR = mkdir -p # legacy
|
||||||
QMAKE_MKDIR_CMD = test -d %1 || mkdir -p %1
|
QMAKE_MKDIR_CMD = test -d %1 || mkdir -p %1
|
||||||
QMAKE_STREAM_EDITOR = sed
|
QMAKE_STREAM_EDITOR = sed
|
||||||
|
QMAKE_SHELL_NULL_DEVICE = /dev/null
|
||||||
|
|
||||||
equals(QMAKE_HOST.os, Windows) {
|
equals(QMAKE_HOST.os, Windows) {
|
||||||
MINGW_IN_SHELL = 1 # legacy
|
MINGW_IN_SHELL = 1 # legacy
|
||||||
@ -120,7 +122,9 @@ QMAKE_INSTALL_DIR = $$QMAKE_COPY_DIR
|
|||||||
equals(QMAKE_HOST.os, Windows) {
|
equals(QMAKE_HOST.os, Windows) {
|
||||||
QMAKE_SYMBOLIC_LINK = $(QMAKE) -install ln -f -s
|
QMAKE_SYMBOLIC_LINK = $(QMAKE) -install ln -f -s
|
||||||
QMAKE_LN_SHLIB = $(QMAKE) -install ln -s
|
QMAKE_LN_SHLIB = $(QMAKE) -install ln -s
|
||||||
|
QMAKE_SYSTEM_NULL_DEVICE = NUL
|
||||||
} else {
|
} else {
|
||||||
QMAKE_SYMBOLIC_LINK = ln -f -s
|
QMAKE_SYMBOLIC_LINK = ln -f -s
|
||||||
QMAKE_LN_SHLIB = ln -s
|
QMAKE_LN_SHLIB = ln -s
|
||||||
|
QMAKE_SYSTEM_NULL_DEVICE = /dev/null
|
||||||
}
|
}
|
||||||
|
@ -32,15 +32,11 @@ isEmpty($${target_prefix}.INCDIRS) {
|
|||||||
# Get default include and library paths from compiler
|
# Get default include and library paths from compiler
|
||||||
#
|
#
|
||||||
gcc {
|
gcc {
|
||||||
!equals(QMAKE_HOST.os, Windows) {
|
cmd_suffix = "<$$QMAKE_SYSTEM_NULL_DEVICE >$$QMAKE_SYSTEM_NULL_DEVICE"
|
||||||
cmd_prefix = "LC_ALL=C"
|
equals(QMAKE_HOST.os, Windows): \
|
||||||
cmd_suffix = "</dev/null >/dev/null"
|
|
||||||
null_file = /dev/null
|
|
||||||
} else {
|
|
||||||
cmd_prefix = "set LC_ALL=C&"
|
cmd_prefix = "set LC_ALL=C&"
|
||||||
cmd_suffix = "<NUL >NUL"
|
else: \
|
||||||
null_file = NUL
|
cmd_prefix = "LC_ALL=C"
|
||||||
}
|
|
||||||
|
|
||||||
cxx_flags = $$QMAKE_CXXFLAGS
|
cxx_flags = $$QMAKE_CXXFLAGS
|
||||||
|
|
||||||
@ -59,7 +55,7 @@ isEmpty($${target_prefix}.INCDIRS) {
|
|||||||
|
|
||||||
rim_qcc: \
|
rim_qcc: \
|
||||||
# Need the cc1plus and ld command lines to pick up the paths
|
# Need the cc1plus and ld command lines to pick up the paths
|
||||||
cxx_flags += $$QMAKE_LFLAGS_SHLIB -o $$null_file -v
|
cxx_flags += $$QMAKE_LFLAGS_SHLIB -o $$QMAKE_SYSTEM_NULL_DEVICE -v
|
||||||
else: darwin:clang: \
|
else: darwin:clang: \
|
||||||
# Need to link to pick up library paths
|
# Need to link to pick up library paths
|
||||||
cxx_flags += $$QMAKE_LFLAGS_SHLIB -o /dev/null -v -Wl,-v
|
cxx_flags += $$QMAKE_LFLAGS_SHLIB -o /dev/null -v -Wl,-v
|
||||||
@ -175,9 +171,8 @@ defineReplace(qtVariablesFromMSVC) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
defineReplace(qtVariablesFromGCC) {
|
defineReplace(qtVariablesFromGCC) {
|
||||||
null_device = /dev/null
|
ret = $$system("$$1 -E $$system_quote($$PWD/data/macros.cpp) \
|
||||||
equals(QMAKE_HOST.os, Windows): null_device = NUL
|
<$$QMAKE_SYSTEM_NULL_DEVICE 2>$$QMAKE_SYSTEM_NULL_DEVICE", lines, ec)
|
||||||
ret = $$system("$$1 -E $$system_quote($$PWD/data/macros.cpp) <$$null_device 2>$$null_device", lines, ec)
|
|
||||||
!equals(ec, 0): qtCompilerErrror($$1)
|
!equals(ec, 0): qtCompilerErrror($$1)
|
||||||
return($$ret)
|
return($$ret)
|
||||||
}
|
}
|
||||||
|
@ -36,12 +36,6 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
#define NULL_DEVICE "NUL"
|
|
||||||
#else
|
|
||||||
#define NULL_DEVICE "/dev/null"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
MingwMakefileGenerator::MingwMakefileGenerator() : Win32MakefileGenerator()
|
MingwMakefileGenerator::MingwMakefileGenerator() : Win32MakefileGenerator()
|
||||||
@ -329,7 +323,7 @@ void MingwMakefileGenerator::writeBuildRulesPart(QTextStream &t)
|
|||||||
if(!project->isEmpty("QMAKE_PRE_LINK"))
|
if(!project->isEmpty("QMAKE_PRE_LINK"))
|
||||||
t << "\n\t" <<var("QMAKE_PRE_LINK");
|
t << "\n\t" <<var("QMAKE_PRE_LINK");
|
||||||
if(project->isActiveConfig("staticlib") && project->first("TEMPLATE") == "lib") {
|
if(project->isActiveConfig("staticlib") && project->first("TEMPLATE") == "lib") {
|
||||||
t << "\n\t-$(DEL_FILE) $(DESTDIR_TARGET) 2>" NULL_DEVICE;
|
t << "\n\t-$(DEL_FILE) $(DESTDIR_TARGET) 2>" << var("QMAKE_SHELL_NULL_DEVICE");
|
||||||
if (project->values("OBJECTS").count() < var("QMAKE_LINK_OBJECT_MAX").toInt()) {
|
if (project->values("OBJECTS").count() < var("QMAKE_LINK_OBJECT_MAX").toInt()) {
|
||||||
t << "\n\t$(LIB) $(DESTDIR_TARGET) " << objectsLinkLine << " " ;
|
t << "\n\t$(LIB) $(DESTDIR_TARGET) " << objectsLinkLine << " " ;
|
||||||
} else {
|
} else {
|
||||||
|
64
src/3rdparty/angle/LICENSE
vendored
64
src/3rdparty/angle/LICENSE
vendored
@ -1,32 +1,32 @@
|
|||||||
// Copyright (C) 2002-2013 The ANGLE Project Authors.
|
Copyright (C) 2002-2013 The ANGLE Project Authors.
|
||||||
// All rights reserved.
|
All rights reserved.
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions
|
modification, are permitted provided that the following conditions
|
||||||
// are met:
|
are met:
|
||||||
//
|
|
||||||
// Redistributions of source code must retain the above copyright
|
Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
notice, this list of conditions and the following disclaimer.
|
||||||
//
|
|
||||||
// Redistributions in binary form must reproduce the above
|
Redistributions in binary form must reproduce the above
|
||||||
// copyright notice, this list of conditions and the following
|
copyright notice, this list of conditions and the following
|
||||||
// disclaimer in the documentation and/or other materials provided
|
disclaimer in the documentation and/or other materials provided
|
||||||
// with the distribution.
|
with the distribution.
|
||||||
//
|
|
||||||
// Neither the name of TransGaming Inc., Google Inc., 3DLabs Inc.
|
Neither the name of TransGaming Inc., Google Inc., 3DLabs Inc.
|
||||||
// Ltd., nor the names of their contributors may be used to endorse
|
Ltd., nor the names of their contributors may be used to endorse
|
||||||
// or promote products derived from this software without specific
|
or promote products derived from this software without specific
|
||||||
// prior written permission.
|
prior written permission.
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
15
src/3rdparty/sqlite/patches/0001-Fix-CVE-2017-10989-in-sqlite.patch
vendored
Normal file
15
src/3rdparty/sqlite/patches/0001-Fix-CVE-2017-10989-in-sqlite.patch
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
diff --git a/src/3rdparty/sqlite/sqlite3.c b/src/3rdparty/sqlite/sqlite3.c
|
||||||
|
index 7f5e75921f..f5c6180a03 100644
|
||||||
|
--- a/src/3rdparty/sqlite/sqlite3.c
|
||||||
|
+++ b/src/3rdparty/sqlite/sqlite3.c
|
||||||
|
@@ -165733,6 +165733,10 @@ static int getNodeSize(
|
||||||
|
rc = getIntFromStmt(db, zSql, &pRtree->iNodeSize);
|
||||||
|
if( rc!=SQLITE_OK ){
|
||||||
|
*pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
|
||||||
|
+ }else if( pRtree->iNodeSize<(512-64) ){
|
||||||
|
+ rc = SQLITE_CORRUPT;
|
||||||
|
+ *pzErr = sqlite3_mprintf("undersize RTree blobs in \"%q_node\"",
|
||||||
|
+ pRtree->zName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
4
src/3rdparty/sqlite/sqlite3.c
vendored
4
src/3rdparty/sqlite/sqlite3.c
vendored
@ -165733,6 +165733,10 @@ static int getNodeSize(
|
|||||||
rc = getIntFromStmt(db, zSql, &pRtree->iNodeSize);
|
rc = getIntFromStmt(db, zSql, &pRtree->iNodeSize);
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
*pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
|
*pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
|
||||||
|
}else if( pRtree->iNodeSize<(512-64) ){
|
||||||
|
rc = SQLITE_CORRUPT;
|
||||||
|
*pzErr = sqlite3_mprintf("undersize RTree blobs in \"%q_node\"",
|
||||||
|
pRtree->zName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -585,7 +585,7 @@ angle_d3d11: SHADERS = VS_Passthrough2D \
|
|||||||
for (SHADER, SHADERS) {
|
for (SHADER, SHADERS) {
|
||||||
INPUT = $$eval($${SHADER}.input)
|
INPUT = $$eval($${SHADER}.input)
|
||||||
OUT_DIR = $$OUT_PWD/libANGLE/$$relative_path($$dirname($$INPUT), $$ANGLE_DIR/src/libANGLE)/compiled
|
OUT_DIR = $$OUT_PWD/libANGLE/$$relative_path($$dirname($$INPUT), $$ANGLE_DIR/src/libANGLE)/compiled
|
||||||
fxc_$${SHADER}.commands = $$FXC /nologo /E $${SHADER} /T $$eval($${SHADER}.type) /Fh ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
|
fxc_$${SHADER}.commands = $$FXC -nologo -E $${SHADER} -T $$eval($${SHADER}.type) -Fh ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
|
||||||
fxc_$${SHADER}.output = $$OUT_DIR/$$eval($${SHADER}.output)
|
fxc_$${SHADER}.output = $$OUT_DIR/$$eval($${SHADER}.output)
|
||||||
fxc_$${SHADER}.input = $$INPUT
|
fxc_$${SHADER}.input = $$INPUT
|
||||||
fxc_$${SHADER}.dependency_type = TYPE_C
|
fxc_$${SHADER}.dependency_type = TYPE_C
|
||||||
|
@ -48,8 +48,6 @@ win32 {
|
|||||||
mingw {
|
mingw {
|
||||||
# otherwise mingw headers do not declare common functions like putenv
|
# otherwise mingw headers do not declare common functions like putenv
|
||||||
CONFIG -= strict_c++
|
CONFIG -= strict_c++
|
||||||
# Override MinGW's definition in _mingw.h
|
|
||||||
DEFINES += WINVER=0x600 _WIN32_WINNT=0x0600
|
|
||||||
}
|
}
|
||||||
LIBS_PRIVATE += -lws2_32
|
LIBS_PRIVATE += -lws2_32
|
||||||
!winrt {
|
!winrt {
|
||||||
|
@ -99,8 +99,6 @@ gcc:ltcg {
|
|||||||
SOURCES += $$VERSIONTAGGING_SOURCES
|
SOURCES += $$VERSIONTAGGING_SOURCES
|
||||||
}
|
}
|
||||||
|
|
||||||
# On AARCH64 the fp16 extension is mandatory, so we don't need the conversion tables.
|
|
||||||
!contains(QT_ARCH, "arm64") {
|
|
||||||
QMAKE_QFLOAT16_TABLES_GENERATE = global/qfloat16.h
|
QMAKE_QFLOAT16_TABLES_GENERATE = global/qfloat16.h
|
||||||
|
|
||||||
qtPrepareTool(QMAKE_QFLOAT16_TABLES, qfloat16-tables)
|
qtPrepareTool(QMAKE_QFLOAT16_TABLES, qfloat16-tables)
|
||||||
@ -111,4 +109,3 @@ gcc:ltcg {
|
|||||||
qfloat16_tables.input = QMAKE_QFLOAT16_TABLES_GENERATE
|
qfloat16_tables.input = QMAKE_QFLOAT16_TABLES_GENERATE
|
||||||
qfloat16_tables.variable_out = SOURCES
|
qfloat16_tables.variable_out = SOURCES
|
||||||
QMAKE_EXTRA_COMPILERS += qfloat16_tables
|
QMAKE_EXTRA_COMPILERS += qfloat16_tables
|
||||||
}
|
|
||||||
|
@ -4296,6 +4296,7 @@ bool QInternal::activateCallbacks(Callback cb, void **parameters)
|
|||||||
/*!
|
/*!
|
||||||
\macro qDebug(const char *message, ...)
|
\macro qDebug(const char *message, ...)
|
||||||
\relates <QtGlobal>
|
\relates <QtGlobal>
|
||||||
|
\threadsafe
|
||||||
|
|
||||||
Calls the message handler with the debug message \a message. If no
|
Calls the message handler with the debug message \a message. If no
|
||||||
message handler has been installed, the message is printed to
|
message handler has been installed, the message is printed to
|
||||||
@ -4332,6 +4333,7 @@ bool QInternal::activateCallbacks(Callback cb, void **parameters)
|
|||||||
/*!
|
/*!
|
||||||
\macro qInfo(const char *message, ...)
|
\macro qInfo(const char *message, ...)
|
||||||
\relates <QtGlobal>
|
\relates <QtGlobal>
|
||||||
|
\threadsafe
|
||||||
\since 5.5
|
\since 5.5
|
||||||
|
|
||||||
Calls the message handler with the informational message \a message. If no
|
Calls the message handler with the informational message \a message. If no
|
||||||
@ -4369,6 +4371,7 @@ bool QInternal::activateCallbacks(Callback cb, void **parameters)
|
|||||||
/*!
|
/*!
|
||||||
\macro qWarning(const char *message, ...)
|
\macro qWarning(const char *message, ...)
|
||||||
\relates <QtGlobal>
|
\relates <QtGlobal>
|
||||||
|
\threadsafe
|
||||||
|
|
||||||
Calls the message handler with the warning message \a message. If no
|
Calls the message handler with the warning message \a message. If no
|
||||||
message handler has been installed, the message is printed to
|
message handler has been installed, the message is printed to
|
||||||
@ -4406,6 +4409,7 @@ bool QInternal::activateCallbacks(Callback cb, void **parameters)
|
|||||||
/*!
|
/*!
|
||||||
\macro qCritical(const char *message, ...)
|
\macro qCritical(const char *message, ...)
|
||||||
\relates <QtGlobal>
|
\relates <QtGlobal>
|
||||||
|
\threadsafe
|
||||||
|
|
||||||
Calls the message handler with the critical message \a message. If no
|
Calls the message handler with the critical message \a message. If no
|
||||||
message handler has been installed, the message is printed to
|
message handler has been installed, the message is printed to
|
||||||
|
@ -154,15 +154,19 @@ class SystemRandom
|
|||||||
{
|
{
|
||||||
static QBasicAtomicInt s_fdp1; // "file descriptor plus 1"
|
static QBasicAtomicInt s_fdp1; // "file descriptor plus 1"
|
||||||
static int openDevice();
|
static int openDevice();
|
||||||
|
#ifdef Q_CC_GNU
|
||||||
|
// If it's not GCC or GCC-like, then we'll leak the file descriptor
|
||||||
|
__attribute__((destructor))
|
||||||
|
#endif
|
||||||
|
static void closeDevice();
|
||||||
SystemRandom() {}
|
SystemRandom() {}
|
||||||
~SystemRandom();
|
|
||||||
public:
|
public:
|
||||||
enum { EfficientBufferFill = true };
|
enum { EfficientBufferFill = true };
|
||||||
static qssize_t fillBuffer(void *buffer, qssize_t count);
|
static qssize_t fillBuffer(void *buffer, qssize_t count);
|
||||||
};
|
};
|
||||||
QBasicAtomicInt SystemRandom::s_fdp1 = Q_BASIC_ATOMIC_INITIALIZER(0);
|
QBasicAtomicInt SystemRandom::s_fdp1 = Q_BASIC_ATOMIC_INITIALIZER(0);
|
||||||
|
|
||||||
SystemRandom::~SystemRandom()
|
void SystemRandom::closeDevice()
|
||||||
{
|
{
|
||||||
int fd = s_fdp1.loadAcquire() - 1;
|
int fd = s_fdp1.loadAcquire() - 1;
|
||||||
if (fd >= 0)
|
if (fd >= 0)
|
||||||
|
@ -62,8 +62,16 @@ public:
|
|||||||
static Q_CORE_EXPORT quint64 generate64();
|
static Q_CORE_EXPORT quint64 generate64();
|
||||||
static double generateDouble()
|
static double generateDouble()
|
||||||
{
|
{
|
||||||
// use get64() to get enough bits
|
// IEEE 754 double precision has:
|
||||||
return double(generate64()) / ((std::numeric_limits<quint64>::max)() + double(1.0));
|
// 1 bit sign
|
||||||
|
// 10 bits exponent
|
||||||
|
// 53 bits mantissa
|
||||||
|
// In order for our result to be normalized in the range [0, 1), we
|
||||||
|
// need exactly 53 bits of random data. Use generate64() to get enough.
|
||||||
|
quint64 x = generate64();
|
||||||
|
quint64 limit = Q_UINT64_C(1) << std::numeric_limits<double>::digits;
|
||||||
|
x >>= std::numeric_limits<quint64>::digits - std::numeric_limits<double>::digits;
|
||||||
|
return double(x) / double(limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
static qreal bounded(qreal sup)
|
static qreal bounded(qreal sup)
|
||||||
|
@ -48,10 +48,10 @@
|
|||||||
#if defined(Q_CC_MINGW)
|
#if defined(Q_CC_MINGW)
|
||||||
// mingw's windows.h does not set _WIN32_WINNT, resulting breaking compilation
|
// mingw's windows.h does not set _WIN32_WINNT, resulting breaking compilation
|
||||||
# ifndef WINVER
|
# ifndef WINVER
|
||||||
# define WINVER 0x600
|
# define WINVER 0x601
|
||||||
# endif
|
# endif
|
||||||
# ifndef _WIN32_WINNT
|
# ifndef _WIN32_WINNT
|
||||||
# define _WIN32_WINNT 0x600
|
# define _WIN32_WINNT 0x601
|
||||||
# endif
|
# endif
|
||||||
# ifndef NTDDI_VERSION
|
# ifndef NTDDI_VERSION
|
||||||
# define NTDDI_VERSION 0x06000000
|
# define NTDDI_VERSION 0x06000000
|
||||||
|
@ -595,6 +595,9 @@ QByteArray QFileSystemEngine::id(const QFileSystemEntry &entry)
|
|||||||
params.dwSize = sizeof(params);
|
params.dwSize = sizeof(params);
|
||||||
params.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
|
params.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
|
||||||
params.dwFileFlags = FILE_FLAG_BACKUP_SEMANTICS;
|
params.dwFileFlags = FILE_FLAG_BACKUP_SEMANTICS;
|
||||||
|
params.dwSecurityQosFlags = SECURITY_ANONYMOUS;
|
||||||
|
params.lpSecurityAttributes = NULL;
|
||||||
|
params.hTemplateFile = NULL;
|
||||||
const HANDLE handle =
|
const HANDLE handle =
|
||||||
CreateFile2((const wchar_t*)entry.nativeFilePath().utf16(), 0,
|
CreateFile2((const wchar_t*)entry.nativeFilePath().utf16(), 0,
|
||||||
FILE_SHARE_READ, OPEN_EXISTING, ¶ms);
|
FILE_SHARE_READ, OPEN_EXISTING, ¶ms);
|
||||||
|
@ -445,6 +445,7 @@ void QLoggingCategory::setFilterRules(const QString &rules)
|
|||||||
/*!
|
/*!
|
||||||
\macro qCDebug(category)
|
\macro qCDebug(category)
|
||||||
\relates QLoggingCategory
|
\relates QLoggingCategory
|
||||||
|
\threadsafe
|
||||||
\since 5.2
|
\since 5.2
|
||||||
|
|
||||||
Returns an output stream for debug messages in the logging category
|
Returns an output stream for debug messages in the logging category
|
||||||
@ -469,6 +470,7 @@ void QLoggingCategory::setFilterRules(const QString &rules)
|
|||||||
/*!
|
/*!
|
||||||
\macro qCDebug(category, const char *message, ...)
|
\macro qCDebug(category, const char *message, ...)
|
||||||
\relates QLoggingCategory
|
\relates QLoggingCategory
|
||||||
|
\threadsafe
|
||||||
\since 5.3
|
\since 5.3
|
||||||
|
|
||||||
Logs a debug message \a message in the logging category \a category.
|
Logs a debug message \a message in the logging category \a category.
|
||||||
@ -490,6 +492,7 @@ void QLoggingCategory::setFilterRules(const QString &rules)
|
|||||||
/*!
|
/*!
|
||||||
\macro qCInfo(category)
|
\macro qCInfo(category)
|
||||||
\relates QLoggingCategory
|
\relates QLoggingCategory
|
||||||
|
\threadsafe
|
||||||
\since 5.5
|
\since 5.5
|
||||||
|
|
||||||
Returns an output stream for informational messages in the logging category
|
Returns an output stream for informational messages in the logging category
|
||||||
@ -514,6 +517,7 @@ void QLoggingCategory::setFilterRules(const QString &rules)
|
|||||||
/*!
|
/*!
|
||||||
\macro qCInfo(category, const char *message, ...)
|
\macro qCInfo(category, const char *message, ...)
|
||||||
\relates QLoggingCategory
|
\relates QLoggingCategory
|
||||||
|
\threadsafe
|
||||||
\since 5.5
|
\since 5.5
|
||||||
|
|
||||||
Logs an informational message \a message in the logging category \a category.
|
Logs an informational message \a message in the logging category \a category.
|
||||||
@ -535,6 +539,7 @@ void QLoggingCategory::setFilterRules(const QString &rules)
|
|||||||
/*!
|
/*!
|
||||||
\macro qCWarning(category)
|
\macro qCWarning(category)
|
||||||
\relates QLoggingCategory
|
\relates QLoggingCategory
|
||||||
|
\threadsafe
|
||||||
\since 5.2
|
\since 5.2
|
||||||
|
|
||||||
Returns an output stream for warning messages in the logging category
|
Returns an output stream for warning messages in the logging category
|
||||||
@ -559,6 +564,7 @@ void QLoggingCategory::setFilterRules(const QString &rules)
|
|||||||
/*!
|
/*!
|
||||||
\macro qCWarning(category, const char *message, ...)
|
\macro qCWarning(category, const char *message, ...)
|
||||||
\relates QLoggingCategory
|
\relates QLoggingCategory
|
||||||
|
\threadsafe
|
||||||
\since 5.3
|
\since 5.3
|
||||||
|
|
||||||
Logs a warning message \a message in the logging category \a category.
|
Logs a warning message \a message in the logging category \a category.
|
||||||
@ -580,6 +586,7 @@ void QLoggingCategory::setFilterRules(const QString &rules)
|
|||||||
/*!
|
/*!
|
||||||
\macro qCCritical(category)
|
\macro qCCritical(category)
|
||||||
\relates QLoggingCategory
|
\relates QLoggingCategory
|
||||||
|
\threadsafe
|
||||||
\since 5.2
|
\since 5.2
|
||||||
|
|
||||||
Returns an output stream for critical messages in the logging category
|
Returns an output stream for critical messages in the logging category
|
||||||
@ -604,6 +611,7 @@ void QLoggingCategory::setFilterRules(const QString &rules)
|
|||||||
/*!
|
/*!
|
||||||
\macro qCCritical(category, const char *message, ...)
|
\macro qCCritical(category, const char *message, ...)
|
||||||
\relates QLoggingCategory
|
\relates QLoggingCategory
|
||||||
|
\threadsafe
|
||||||
\since 5.3
|
\since 5.3
|
||||||
|
|
||||||
Logs a critical message \a message in the logging category \a category.
|
Logs a critical message \a message in the logging category \a category.
|
||||||
|
@ -499,9 +499,10 @@ public:
|
|||||||
|
|
||||||
InvalidFragmentError = Fragment << 8,
|
InvalidFragmentError = Fragment << 8,
|
||||||
|
|
||||||
// the following two cases are only possible in combination
|
// the following three cases are only possible in combination with
|
||||||
// with presence/absence of the authority and scheme. See validityError().
|
// presence/absence of the path, authority and scheme. See validityError().
|
||||||
AuthorityPresentAndPathIsRelative = Authority << 8 | Path << 8 | 0x10000,
|
AuthorityPresentAndPathIsRelative = Authority << 8 | Path << 8 | 0x10000,
|
||||||
|
AuthorityAbsentAndPathIsDoubleSlash,
|
||||||
RelativeUrlPathContainsColonBeforeSlash = Scheme << 8 | Authority << 8 | Path << 8 | 0x10000,
|
RelativeUrlPathContainsColonBeforeSlash = Scheme << 8 | Authority << 8 | Path << 8 | 0x10000,
|
||||||
|
|
||||||
NoError = 0
|
NoError = 0
|
||||||
@ -1627,19 +1628,32 @@ inline QUrlPrivate::ErrorCode QUrlPrivate::validityError(QString *source, int *p
|
|||||||
return error->code;
|
return error->code;
|
||||||
}
|
}
|
||||||
|
|
||||||
// There are two more cases of invalid URLs that QUrl recognizes and they
|
// There are three more cases of invalid URLs that QUrl recognizes and they
|
||||||
// are only possible with constructed URLs (setXXX methods), not with
|
// are only possible with constructed URLs (setXXX methods), not with
|
||||||
// parsing. Therefore, they are tested here.
|
// parsing. Therefore, they are tested here.
|
||||||
//
|
//
|
||||||
// The two cases are a non-empty path that doesn't start with a slash and:
|
// Two cases are a non-empty path that doesn't start with a slash and:
|
||||||
// - with an authority
|
// - with an authority
|
||||||
// - without an authority, without scheme but the path with a colon before
|
// - without an authority, without scheme but the path with a colon before
|
||||||
// the first slash
|
// the first slash
|
||||||
|
// The third case is an empty authority and a non-empty path that starts
|
||||||
|
// with "//".
|
||||||
// Those cases are considered invalid because toString() would produce a URL
|
// Those cases are considered invalid because toString() would produce a URL
|
||||||
// that wouldn't be parsed back to the same QUrl.
|
// that wouldn't be parsed back to the same QUrl.
|
||||||
|
|
||||||
if (path.isEmpty() || path.at(0) == QLatin1Char('/'))
|
if (path.isEmpty())
|
||||||
return NoError;
|
return NoError;
|
||||||
|
if (path.at(0) == QLatin1Char('/')) {
|
||||||
|
if (sectionIsPresent & QUrlPrivate::Authority || port != -1 ||
|
||||||
|
path.length() == 1 || path.at(1) != QLatin1Char('/'))
|
||||||
|
return NoError;
|
||||||
|
if (source) {
|
||||||
|
*source = path;
|
||||||
|
*position = 0;
|
||||||
|
}
|
||||||
|
return AuthorityAbsentAndPathIsDoubleSlash;
|
||||||
|
}
|
||||||
|
|
||||||
if (sectionIsPresent & QUrlPrivate::Host) {
|
if (sectionIsPresent & QUrlPrivate::Host) {
|
||||||
if (source) {
|
if (source) {
|
||||||
*source = path;
|
*source = path;
|
||||||
@ -2514,10 +2528,7 @@ void QUrl::setPath(const QString &path, ParsingMode mode)
|
|||||||
mode = TolerantMode;
|
mode = TolerantMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
int from = 0;
|
d->setPath(data, 0, data.length());
|
||||||
while (from < data.length() - 2 && data.midRef(from, 2) == QLatin1String("//"))
|
|
||||||
++from;
|
|
||||||
d->setPath(data, from, data.length());
|
|
||||||
|
|
||||||
// optimized out, since there is no path delimiter
|
// optimized out, since there is no path delimiter
|
||||||
// if (path.isNull())
|
// if (path.isNull())
|
||||||
@ -3989,6 +4000,8 @@ static QString errorMessage(QUrlPrivate::ErrorCode errorCode, const QString &err
|
|||||||
|
|
||||||
case QUrlPrivate::AuthorityPresentAndPathIsRelative:
|
case QUrlPrivate::AuthorityPresentAndPathIsRelative:
|
||||||
return QStringLiteral("Path component is relative and authority is present");
|
return QStringLiteral("Path component is relative and authority is present");
|
||||||
|
case QUrlPrivate::AuthorityAbsentAndPathIsDoubleSlash:
|
||||||
|
return QStringLiteral("Path component starts with '//' and authority is absent");
|
||||||
case QUrlPrivate::RelativeUrlPathContainsColonBeforeSlash:
|
case QUrlPrivate::RelativeUrlPathContainsColonBeforeSlash:
|
||||||
return QStringLiteral("Relative URL's path component contains ':' before any '/'");
|
return QStringLiteral("Relative URL's path component contains ':' before any '/'");
|
||||||
}
|
}
|
||||||
|
@ -170,10 +170,10 @@ QT_BEGIN_NAMESPACE
|
|||||||
\value LeaveEditFocus An editor widget loses focus for editing. QT_KEYPAD_NAVIGATION must be defined.
|
\value LeaveEditFocus An editor widget loses focus for editing. QT_KEYPAD_NAVIGATION must be defined.
|
||||||
\value LeaveWhatsThisMode Send to toplevel widgets when the application leaves "What's This?" mode.
|
\value LeaveWhatsThisMode Send to toplevel widgets when the application leaves "What's This?" mode.
|
||||||
\value LocaleChange The system locale has changed.
|
\value LocaleChange The system locale has changed.
|
||||||
\value NonClientAreaMouseButtonDblClick A mouse double click occurred outside the client area.
|
\value NonClientAreaMouseButtonDblClick A mouse double click occurred outside the client area (QMouseEvent).
|
||||||
\value NonClientAreaMouseButtonPress A mouse button press occurred outside the client area.
|
\value NonClientAreaMouseButtonPress A mouse button press occurred outside the client area (QMouseEvent).
|
||||||
\value NonClientAreaMouseButtonRelease A mouse button release occurred outside the client area.
|
\value NonClientAreaMouseButtonRelease A mouse button release occurred outside the client area (QMouseEvent).
|
||||||
\value NonClientAreaMouseMove A mouse move occurred outside the client area.
|
\value NonClientAreaMouseMove A mouse move occurred outside the client area (QMouseEvent).
|
||||||
\value MacSizeChange The user changed his widget sizes (\macos only).
|
\value MacSizeChange The user changed his widget sizes (\macos only).
|
||||||
\value MetaCall An asynchronous method invocation via QMetaObject::invokeMethod().
|
\value MetaCall An asynchronous method invocation via QMetaObject::invokeMethod().
|
||||||
\value ModifiedChange Widgets modification state has been changed.
|
\value ModifiedChange Widgets modification state has been changed.
|
||||||
|
@ -251,7 +251,7 @@ class Q_CORE_EXPORT QMutex
|
|||||||
public:
|
public:
|
||||||
enum RecursionMode { NonRecursive, Recursive };
|
enum RecursionMode { NonRecursive, Recursive };
|
||||||
|
|
||||||
inline explicit QMutex(RecursionMode mode = NonRecursive) Q_DECL_NOTHROW { Q_UNUSED(mode); }
|
inline Q_DECL_CONSTEXPR explicit QMutex(RecursionMode = NonRecursive) Q_DECL_NOTHROW { }
|
||||||
|
|
||||||
inline void lock() Q_DECL_NOTHROW {}
|
inline void lock() Q_DECL_NOTHROW {}
|
||||||
inline bool tryLock(int timeout = 0) Q_DECL_NOTHROW { Q_UNUSED(timeout); return true; }
|
inline bool tryLock(int timeout = 0) Q_DECL_NOTHROW { Q_UNUSED(timeout); return true; }
|
||||||
|
@ -73,7 +73,7 @@ public:
|
|||||||
\internal
|
\internal
|
||||||
*/
|
*/
|
||||||
QThreadPoolThread::QThreadPoolThread(QThreadPoolPrivate *manager)
|
QThreadPoolThread::QThreadPoolThread(QThreadPoolPrivate *manager)
|
||||||
:manager(manager), runnable(0)
|
:manager(manager), runnable(nullptr)
|
||||||
{
|
{
|
||||||
setStackSize(manager->stackSize);
|
setStackSize(manager->stackSize);
|
||||||
}
|
}
|
||||||
@ -86,7 +86,7 @@ void QThreadPoolThread::run()
|
|||||||
QMutexLocker locker(&manager->mutex);
|
QMutexLocker locker(&manager->mutex);
|
||||||
for(;;) {
|
for(;;) {
|
||||||
QRunnable *r = runnable;
|
QRunnable *r = runnable;
|
||||||
runnable = 0;
|
runnable = nullptr;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (r) {
|
if (r) {
|
||||||
@ -118,8 +118,19 @@ void QThreadPoolThread::run()
|
|||||||
if (manager->tooManyThreadsActive())
|
if (manager->tooManyThreadsActive())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
r = !manager->queue.isEmpty() ? manager->queue.takeFirst().first : 0;
|
if (manager->queue.isEmpty()) {
|
||||||
} while (r != 0);
|
r = nullptr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
QueuePage *page = manager->queue.first();
|
||||||
|
r = page->pop();
|
||||||
|
|
||||||
|
if (page->isFinished()) {
|
||||||
|
manager->queue.removeFirst();
|
||||||
|
delete page;
|
||||||
|
}
|
||||||
|
} while (true);
|
||||||
|
|
||||||
if (manager->isExiting) {
|
if (manager->isExiting) {
|
||||||
registerThreadInactive();
|
registerThreadInactive();
|
||||||
@ -160,6 +171,7 @@ QThreadPoolPrivate:: QThreadPoolPrivate()
|
|||||||
|
|
||||||
bool QThreadPoolPrivate::tryStart(QRunnable *task)
|
bool QThreadPoolPrivate::tryStart(QRunnable *task)
|
||||||
{
|
{
|
||||||
|
Q_ASSERT(task != nullptr);
|
||||||
if (allThreads.isEmpty()) {
|
if (allThreads.isEmpty()) {
|
||||||
// always create at least one thread
|
// always create at least one thread
|
||||||
startThread(task);
|
startThread(task);
|
||||||
@ -180,7 +192,7 @@ bool QThreadPoolPrivate::tryStart(QRunnable *task)
|
|||||||
if (!expiredThreads.isEmpty()) {
|
if (!expiredThreads.isEmpty()) {
|
||||||
// restart an expired thread
|
// restart an expired thread
|
||||||
QThreadPoolThread *thread = expiredThreads.dequeue();
|
QThreadPoolThread *thread = expiredThreads.dequeue();
|
||||||
Q_ASSERT(thread->runnable == 0);
|
Q_ASSERT(thread->runnable == nullptr);
|
||||||
|
|
||||||
++activeThreads;
|
++activeThreads;
|
||||||
|
|
||||||
@ -196,22 +208,25 @@ bool QThreadPoolPrivate::tryStart(QRunnable *task)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool operator<(int priority, const QPair<QRunnable *, int> &p)
|
inline bool comparePriority(int priority, const QueuePage *p)
|
||||||
{ return p.second < priority; }
|
{
|
||||||
inline bool operator<(const QPair<QRunnable *, int> &p, int priority)
|
return p->priority() < priority;
|
||||||
{ return priority < p.second; }
|
}
|
||||||
|
|
||||||
void QThreadPoolPrivate::enqueueTask(QRunnable *runnable, int priority)
|
void QThreadPoolPrivate::enqueueTask(QRunnable *runnable, int priority)
|
||||||
{
|
{
|
||||||
|
Q_ASSERT(runnable != nullptr);
|
||||||
if (runnable->autoDelete())
|
if (runnable->autoDelete())
|
||||||
++runnable->ref;
|
++runnable->ref;
|
||||||
|
|
||||||
// put it on the queue
|
for (QueuePage *page : qAsConst(queue)) {
|
||||||
QVector<QPair<QRunnable *, int> >::const_iterator begin = queue.constBegin();
|
if (page->priority() == priority && !page->isFull()) {
|
||||||
QVector<QPair<QRunnable *, int> >::const_iterator it = queue.constEnd();
|
page->push(runnable);
|
||||||
if (it != begin && priority > (*(it - 1)).second)
|
return;
|
||||||
it = std::upper_bound(begin, --it, priority);
|
}
|
||||||
queue.insert(it - begin, qMakePair(runnable, priority));
|
}
|
||||||
|
auto it = std::upper_bound(queue.constBegin(), queue.constEnd(), priority, comparePriority);
|
||||||
|
queue.insert(std::distance(queue.constBegin(), it), new QueuePage(runnable, priority));
|
||||||
}
|
}
|
||||||
|
|
||||||
int QThreadPoolPrivate::activeThreadCount() const
|
int QThreadPoolPrivate::activeThreadCount() const
|
||||||
@ -225,8 +240,18 @@ int QThreadPoolPrivate::activeThreadCount() const
|
|||||||
void QThreadPoolPrivate::tryToStartMoreThreads()
|
void QThreadPoolPrivate::tryToStartMoreThreads()
|
||||||
{
|
{
|
||||||
// try to push tasks on the queue to any available threads
|
// try to push tasks on the queue to any available threads
|
||||||
while (!queue.isEmpty() && tryStart(queue.constFirst().first))
|
while (!queue.isEmpty()) {
|
||||||
|
QueuePage *page = queue.first();
|
||||||
|
if (!tryStart(page->first()))
|
||||||
|
break;
|
||||||
|
|
||||||
|
page->pop();
|
||||||
|
|
||||||
|
if (page->isFinished()) {
|
||||||
queue.removeFirst();
|
queue.removeFirst();
|
||||||
|
delete page;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QThreadPoolPrivate::tooManyThreadsActive() const
|
bool QThreadPoolPrivate::tooManyThreadsActive() const
|
||||||
@ -240,6 +265,7 @@ bool QThreadPoolPrivate::tooManyThreadsActive() const
|
|||||||
*/
|
*/
|
||||||
void QThreadPoolPrivate::startThread(QRunnable *runnable)
|
void QThreadPoolPrivate::startThread(QRunnable *runnable)
|
||||||
{
|
{
|
||||||
|
Q_ASSERT(runnable != nullptr);
|
||||||
QScopedPointer <QThreadPoolThread> thread(new QThreadPoolThread(this));
|
QScopedPointer <QThreadPoolThread> thread(new QThreadPoolThread(this));
|
||||||
thread->setObjectName(QLatin1String("Thread (pooled)"));
|
thread->setObjectName(QLatin1String("Thread (pooled)"));
|
||||||
Q_ASSERT(!allThreads.contains(thread.data())); // if this assert hits, we have an ABA problem (deleted threads don't get removed here)
|
Q_ASSERT(!allThreads.contains(thread.data())); // if this assert hits, we have an ABA problem (deleted threads don't get removed here)
|
||||||
@ -303,12 +329,14 @@ bool QThreadPoolPrivate::waitForDone(int msecs)
|
|||||||
void QThreadPoolPrivate::clear()
|
void QThreadPoolPrivate::clear()
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&mutex);
|
QMutexLocker locker(&mutex);
|
||||||
for (QVector<QPair<QRunnable *, int> >::const_iterator it = queue.constBegin();
|
for (QueuePage *page : qAsConst(queue)) {
|
||||||
it != queue.constEnd(); ++it) {
|
while (!page->isFinished()) {
|
||||||
QRunnable* r = it->first;
|
QRunnable *r = page->pop();
|
||||||
if (r->autoDelete() && !--r->ref)
|
if (r && r->autoDelete() && !--r->ref)
|
||||||
delete r;
|
delete r;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
qDeleteAll(queue);
|
||||||
queue.clear();
|
queue.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -333,22 +361,21 @@ bool QThreadPool::tryTake(QRunnable *runnable)
|
|||||||
{
|
{
|
||||||
Q_D(QThreadPool);
|
Q_D(QThreadPool);
|
||||||
|
|
||||||
if (runnable == 0)
|
if (runnable == nullptr)
|
||||||
return false;
|
return false;
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&d->mutex);
|
QMutexLocker locker(&d->mutex);
|
||||||
|
|
||||||
auto it = d->queue.begin();
|
for (QueuePage *page : qAsConst(d->queue)) {
|
||||||
auto end = d->queue.end();
|
if (page->tryTake(runnable)) {
|
||||||
|
if (page->isFinished()) {
|
||||||
while (it != end) {
|
d->queue.removeOne(page);
|
||||||
if (it->first == runnable) {
|
delete page;
|
||||||
d->queue.erase(it);
|
}
|
||||||
if (runnable->autoDelete())
|
if (runnable->autoDelete())
|
||||||
--runnable->ref; // undo ++ref in start()
|
--runnable->ref; // undo ++ref in start()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
++it;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,6 +63,87 @@
|
|||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class QueuePage {
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
MaxPageSize = 256
|
||||||
|
};
|
||||||
|
|
||||||
|
QueuePage(QRunnable *runnable, int pri)
|
||||||
|
: m_priority(pri)
|
||||||
|
{
|
||||||
|
push(runnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isFull() {
|
||||||
|
return m_lastIndex >= MaxPageSize - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isFinished() {
|
||||||
|
return m_firstIndex > m_lastIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
void push(QRunnable *runnable) {
|
||||||
|
Q_ASSERT(runnable != nullptr);
|
||||||
|
Q_ASSERT(!isFull());
|
||||||
|
m_lastIndex += 1;
|
||||||
|
m_entries[m_lastIndex] = runnable;
|
||||||
|
}
|
||||||
|
|
||||||
|
void skipToNextOrEnd() {
|
||||||
|
while (!isFinished() && m_entries[m_firstIndex] == nullptr) {
|
||||||
|
m_firstIndex += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QRunnable *first() {
|
||||||
|
Q_ASSERT(!isFinished());
|
||||||
|
QRunnable *runnable = m_entries[m_firstIndex];
|
||||||
|
Q_ASSERT(runnable);
|
||||||
|
return runnable;
|
||||||
|
}
|
||||||
|
|
||||||
|
QRunnable *pop() {
|
||||||
|
Q_ASSERT(!isFinished());
|
||||||
|
QRunnable *runnable = first();
|
||||||
|
Q_ASSERT(runnable);
|
||||||
|
|
||||||
|
// clear the entry although this should not be necessary
|
||||||
|
m_entries[m_firstIndex] = nullptr;
|
||||||
|
m_firstIndex += 1;
|
||||||
|
|
||||||
|
// make sure the next runnable returned by first() is not a nullptr
|
||||||
|
skipToNextOrEnd();
|
||||||
|
|
||||||
|
return runnable;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool tryTake(QRunnable *runnable) {
|
||||||
|
Q_ASSERT(!isFinished());
|
||||||
|
for (int i = m_firstIndex; i <= m_lastIndex; i++) {
|
||||||
|
if (m_entries[i] == runnable) {
|
||||||
|
m_entries[i] = nullptr;
|
||||||
|
if (i == m_firstIndex) {
|
||||||
|
// make sure first() does not return a nullptr
|
||||||
|
skipToNextOrEnd();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int priority() const {
|
||||||
|
return m_priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_priority = 0;
|
||||||
|
int m_firstIndex = 0;
|
||||||
|
int m_lastIndex = -1;
|
||||||
|
QRunnable *m_entries[MaxPageSize];
|
||||||
|
};
|
||||||
|
|
||||||
class QThreadPoolThread;
|
class QThreadPoolThread;
|
||||||
class Q_CORE_EXPORT QThreadPoolPrivate : public QObjectPrivate
|
class Q_CORE_EXPORT QThreadPoolPrivate : public QObjectPrivate
|
||||||
{
|
{
|
||||||
@ -84,12 +165,13 @@ public:
|
|||||||
bool waitForDone(int msecs);
|
bool waitForDone(int msecs);
|
||||||
void clear();
|
void clear();
|
||||||
void stealAndRunRunnable(QRunnable *runnable);
|
void stealAndRunRunnable(QRunnable *runnable);
|
||||||
|
void deletePageIfFinished(QueuePage *page);
|
||||||
|
|
||||||
mutable QMutex mutex;
|
mutable QMutex mutex;
|
||||||
QList<QThreadPoolThread *> allThreads;
|
QList<QThreadPoolThread *> allThreads;
|
||||||
QQueue<QThreadPoolThread *> waitingThreads;
|
QQueue<QThreadPoolThread *> waitingThreads;
|
||||||
QQueue<QThreadPoolThread *> expiredThreads;
|
QQueue<QThreadPoolThread *> expiredThreads;
|
||||||
QVector<QPair<QRunnable *, int> > queue;
|
QVector<QueuePage*> queue;
|
||||||
QWaitCondition noActiveThreads;
|
QWaitCondition noActiveThreads;
|
||||||
|
|
||||||
int expiryTimeout = 30000;
|
int expiryTimeout = 30000;
|
||||||
|
@ -195,7 +195,7 @@ QT_BEGIN_NAMESPACE
|
|||||||
\inmodule QtDBus
|
\inmodule QtDBus
|
||||||
\brief Information about one interface on the bus.
|
\brief Information about one interface on the bus.
|
||||||
|
|
||||||
Each interface on D-Bus has an unique \a name, identifying where that interface was defined.
|
Each interface on D-Bus has a unique \a name, identifying where that interface was defined.
|
||||||
Interfaces may have annotations, methods, signals and properties, but none are mandatory.
|
Interfaces may have annotations, methods, signals and properties, but none are mandatory.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -228,7 +228,6 @@ Q_GLOBAL_STATIC(QReadWriteLock, customTypesLock)
|
|||||||
void QDBusMetaType::registerMarshallOperators(int id, MarshallFunction mf,
|
void QDBusMetaType::registerMarshallOperators(int id, MarshallFunction mf,
|
||||||
DemarshallFunction df)
|
DemarshallFunction df)
|
||||||
{
|
{
|
||||||
QByteArray var;
|
|
||||||
QVector<QDBusCustomTypeInfo> *ct = customTypes();
|
QVector<QDBusCustomTypeInfo> *ct = customTypes();
|
||||||
if (id < 0 || !mf || !df || !ct)
|
if (id < 0 || !mf || !df || !ct)
|
||||||
return; // error!
|
return; // error!
|
||||||
|
@ -1124,7 +1124,7 @@ QWheelEvent::QWheelEvent(const QPointF &pos, const QPointF& globalPos,
|
|||||||
The event is propagated up the parent widget chain until a widget
|
The event is propagated up the parent widget chain until a widget
|
||||||
accepts it or an event filter consumes it.
|
accepts it or an event filter consumes it.
|
||||||
|
|
||||||
The QWidget::setEnable() function can be used to enable or disable
|
The QWidget::setEnabled() function can be used to enable or disable
|
||||||
mouse and keyboard events for a widget.
|
mouse and keyboard events for a widget.
|
||||||
|
|
||||||
The event handlers QWidget::keyPressEvent(), QWidget::keyReleaseEvent(),
|
The event handlers QWidget::keyPressEvent(), QWidget::keyReleaseEvent(),
|
||||||
@ -2335,6 +2335,13 @@ QVariant QInputMethodQueryEvent::value(Qt::InputMethodQuery query) const
|
|||||||
cursor and touchpad. Qt recognizes these by their names. Otherwise, if the
|
cursor and touchpad. Qt recognizes these by their names. Otherwise, if the
|
||||||
tablet is configured to use the evdev driver, there will be only one device
|
tablet is configured to use the evdev driver, there will be only one device
|
||||||
and applications may not be able to distinguish the stylus from the eraser.
|
and applications may not be able to distinguish the stylus from the eraser.
|
||||||
|
|
||||||
|
\section1 Notes for Windows Users
|
||||||
|
|
||||||
|
Tablet support currently requires the WACOM windows driver providing the DLL
|
||||||
|
\c{wintab32.dll} to be installed. It is contained in older packages,
|
||||||
|
for example \c{pentablet_5.3.5-3.exe}.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -2783,13 +2790,13 @@ Q_GLOBAL_STATIC(NativeGestureEventDataHash, g_nativeGestureEventDataHash)
|
|||||||
\a realValue is the \macos event parameter, \a sequenceId and \a intValue are the Windows event parameters.
|
\a realValue is the \macos event parameter, \a sequenceId and \a intValue are the Windows event parameters.
|
||||||
\since 5.10
|
\since 5.10
|
||||||
*/
|
*/
|
||||||
QNativeGestureEvent::QNativeGestureEvent(Qt::NativeGestureType type, const QTouchDevice *dev, const QPointF &localPos, const QPointF &windowPos,
|
QNativeGestureEvent::QNativeGestureEvent(Qt::NativeGestureType type, const QTouchDevice *device, const QPointF &localPos, const QPointF &windowPos,
|
||||||
const QPointF &screenPos, qreal realValue, ulong sequenceId, quint64 intValue)
|
const QPointF &screenPos, qreal realValue, ulong sequenceId, quint64 intValue)
|
||||||
: QInputEvent(QEvent::NativeGesture), mGestureType(type),
|
: QInputEvent(QEvent::NativeGesture), mGestureType(type),
|
||||||
mLocalPos(localPos), mWindowPos(windowPos), mScreenPos(screenPos), mRealValue(realValue),
|
mLocalPos(localPos), mWindowPos(windowPos), mScreenPos(screenPos), mRealValue(realValue),
|
||||||
mSequenceId(sequenceId), mIntValue(intValue)
|
mSequenceId(sequenceId), mIntValue(intValue)
|
||||||
{
|
{
|
||||||
g_nativeGestureEventDataHash->insert(this, dev);
|
g_nativeGestureEventDataHash->insert(this, device);
|
||||||
}
|
}
|
||||||
|
|
||||||
QNativeGestureEvent::~QNativeGestureEvent()
|
QNativeGestureEvent::~QNativeGestureEvent()
|
||||||
|
@ -531,7 +531,7 @@ QVariant QPlatformTheme::defaultThemeHint(ThemeHint hint)
|
|||||||
case UiEffects:
|
case UiEffects:
|
||||||
return QVariant(int(0));
|
return QVariant(int(0));
|
||||||
case SpellCheckUnderlineStyle:
|
case SpellCheckUnderlineStyle:
|
||||||
return QVariant(int(QTextCharFormat::SpellCheckUnderline));
|
return QVariant(int(QTextCharFormat::WaveUnderline));
|
||||||
case TabFocusBehavior:
|
case TabFocusBehavior:
|
||||||
return QVariant(int(Qt::TabFocusAllControls));
|
return QVariant(int(Qt::TabFocusAllControls));
|
||||||
case IconPixmapSizes:
|
case IconPixmapSizes:
|
||||||
|
@ -5572,6 +5572,8 @@ static void qt_alphamapblit_generic(QRasterBuffer *rasterBuffer,
|
|||||||
|
|
||||||
int start = qMax<int>(x, clip.x);
|
int start = qMax<int>(x, clip.x);
|
||||||
int end = qMin<int>(x + mapWidth, clip.x + clip.len);
|
int end = qMin<int>(x + mapWidth, clip.x + clip.len);
|
||||||
|
if (end <= start)
|
||||||
|
continue;
|
||||||
Q_ASSERT(end - start <= buffer_size);
|
Q_ASSERT(end - start <= buffer_size);
|
||||||
QRgba64 *dest = destFetch64((QRgba64*)buffer, rasterBuffer, start, clip.y, end - start);
|
QRgba64 *dest = destFetch64((QRgba64*)buffer, rasterBuffer, start, clip.y, end - start);
|
||||||
|
|
||||||
@ -5845,6 +5847,8 @@ static void qt_alphargbblit_generic(QRasterBuffer *rasterBuffer,
|
|||||||
|
|
||||||
int start = qMax<int>(x, clip.x);
|
int start = qMax<int>(x, clip.x);
|
||||||
int end = qMin<int>(x + mapWidth, clip.x + clip.len);
|
int end = qMin<int>(x + mapWidth, clip.x + clip.len);
|
||||||
|
if (end <= start)
|
||||||
|
continue;
|
||||||
Q_ASSERT(end - start <= buffer_size);
|
Q_ASSERT(end - start <= buffer_size);
|
||||||
QRgba64 *dest = destFetch64((QRgba64*)buffer, rasterBuffer, start, clip.y, end - start);
|
QRgba64 *dest = destFetch64((QRgba64*)buffer, rasterBuffer, start, clip.y, end - start);
|
||||||
|
|
||||||
|
@ -1638,7 +1638,7 @@ void QRasterPaintEngine::stroke(const QVectorPath &path, const QPen &pen)
|
|||||||
QPointF p = lines[i].p1();
|
QPointF p = lines[i].p1();
|
||||||
QLineF line = s->matrix.map(QLineF(QPointF(p.x() - width*0.5, p.y()),
|
QLineF line = s->matrix.map(QLineF(QPointF(p.x() - width*0.5, p.y()),
|
||||||
QPointF(p.x() + width*0.5, p.y())));
|
QPointF(p.x() + width*0.5, p.y())));
|
||||||
d->rasterizer->rasterizeLine(line.p1(), line.p2(), 1);
|
d->rasterizer->rasterizeLine(line.p1(), line.p2(), width / line.length());
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -6261,6 +6261,8 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const
|
|||||||
QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme();
|
QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme();
|
||||||
if (theme)
|
if (theme)
|
||||||
underlineStyle = QTextCharFormat::UnderlineStyle(theme->themeHint(QPlatformTheme::SpellCheckUnderlineStyle).toInt());
|
underlineStyle = QTextCharFormat::UnderlineStyle(theme->themeHint(QPlatformTheme::SpellCheckUnderlineStyle).toInt());
|
||||||
|
if (underlineStyle == QTextCharFormat::SpellCheckUnderline) // still not resolved
|
||||||
|
underlineStyle = QTextCharFormat::WaveUnderline;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (underlineStyle == QTextCharFormat::WaveUnderline) {
|
if (underlineStyle == QTextCharFormat::WaveUnderline) {
|
||||||
|
@ -1147,8 +1147,6 @@ void QDashStroker::processCurrentSubpath()
|
|||||||
|
|
||||||
QLineF cline;
|
QLineF cline;
|
||||||
|
|
||||||
QPainterPath dashPath;
|
|
||||||
|
|
||||||
QSubpathFlatIterator it(&m_elements, m_dashThreshold);
|
QSubpathFlatIterator it(&m_elements, m_dashThreshold);
|
||||||
qfixed2d prev = it.next();
|
qfixed2d prev = it.next();
|
||||||
|
|
||||||
|
@ -1333,9 +1333,9 @@ bool QTextFormat::operator==(const QTextFormat &rhs) const
|
|||||||
\value DashDotLine Dashs and dots are drawn using Qt::DashDotLine.
|
\value DashDotLine Dashs and dots are drawn using Qt::DashDotLine.
|
||||||
\value DashDotDotLine Underlines draw drawn using Qt::DashDotDotLine.
|
\value DashDotDotLine Underlines draw drawn using Qt::DashDotDotLine.
|
||||||
\value WaveUnderline The text is underlined using a wave shaped line.
|
\value WaveUnderline The text is underlined using a wave shaped line.
|
||||||
\value SpellCheckUnderline The underline is drawn depending on the QStyle::SH_SpellCeckUnderlineStyle
|
\value SpellCheckUnderline The underline is drawn depending on the SpellCheckUnderlineStyle
|
||||||
style hint of the QApplication style. By default this is mapped to
|
theme hint of QPlatformTheme. By default this is mapped to
|
||||||
WaveUnderline, on \macos it is mapped to DashDotLine.
|
WaveUnderline, on \macos it is mapped to DotLine.
|
||||||
|
|
||||||
\sa Qt::PenStyle
|
\sa Qt::PenStyle
|
||||||
*/
|
*/
|
||||||
|
@ -381,7 +381,6 @@ void QTextOdfWriter::writeInlineCharacter(QXmlStreamWriter &writer, const QTextF
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (image.isNull()) {
|
if (image.isNull()) {
|
||||||
QString context;
|
|
||||||
if (image.isNull()) { // try direct loading
|
if (image.isNull()) { // try direct loading
|
||||||
name = imageFormat.name(); // remove qrc:/ prefix again
|
name = imageFormat.name(); // remove qrc:/ prefix again
|
||||||
image.load(name);
|
image.load(name);
|
||||||
|
@ -1051,10 +1051,12 @@ void QGridLayoutEngine::setGeometries(const QRectF &contentsGeometry, const QAbs
|
|||||||
if (m_snapToPixelGrid) {
|
if (m_snapToPixelGrid) {
|
||||||
// x and y should already be rounded, but the call to geometryWithin() above might
|
// x and y should already be rounded, but the call to geometryWithin() above might
|
||||||
// result in a geom with x,y at half-pixels (due to centering within the cell)
|
// result in a geom with x,y at half-pixels (due to centering within the cell)
|
||||||
geom.setX(qround(geom.x()));
|
// QRectF may change the width as it wants to maintain the right edge. In this
|
||||||
|
// case the width need to be preserved.
|
||||||
|
geom.moveLeft(qround(geom.x()));
|
||||||
// Do not snap baseline aligned items, since that might cause the baselines to not be aligned.
|
// Do not snap baseline aligned items, since that might cause the baselines to not be aligned.
|
||||||
if (align != Qt::AlignBaseline)
|
if (align != Qt::AlignBaseline)
|
||||||
geom.setY(qround(geom.y()));
|
geom.moveTop(qround(geom.y()));
|
||||||
}
|
}
|
||||||
visualRect(&geom, visualDirection(), contentsGeometry);
|
visualRect(&geom, visualDirection(), contentsGeometry);
|
||||||
item->setGeometry(geom);
|
item->setGeometry(geom);
|
||||||
|
@ -59,7 +59,7 @@
|
|||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
// internal helper. Converts an integer value to an unique string token
|
// internal helper. Converts an integer value to a unique string token
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct HexString
|
struct HexString
|
||||||
{
|
{
|
||||||
|
@ -114,7 +114,7 @@ void QHstsStore::synchronize()
|
|||||||
|
|
||||||
if (observedPolicies.size()) {
|
if (observedPolicies.size()) {
|
||||||
beginHstsGroups();
|
beginHstsGroups();
|
||||||
for (const QHstsPolicy &policy : observedPolicies) {
|
for (const QHstsPolicy &policy : qAsConst(observedPolicies)) {
|
||||||
const QString key(host_name_to_settings_key(policy.host()));
|
const QString key(host_name_to_settings_key(policy.host()));
|
||||||
// If we fail to write a new, updated policy, we also remove the old one.
|
// If we fail to write a new, updated policy, we also remove the old one.
|
||||||
if (policy.isExpired() || !serializePolicy(key, policy))
|
if (policy.isExpired() || !serializePolicy(key, policy))
|
||||||
|
@ -476,6 +476,8 @@ bool QHttpMultiPartIODevice::isSequential() const
|
|||||||
|
|
||||||
bool QHttpMultiPartIODevice::reset()
|
bool QHttpMultiPartIODevice::reset()
|
||||||
{
|
{
|
||||||
|
// Reset QIODevice's data
|
||||||
|
QIODevice::reset();
|
||||||
for (int a = 0; a < multiPart->parts.count(); a++)
|
for (int a = 0; a < multiPart->parts.count(); a++)
|
||||||
if (!multiPart->parts[a].d->reset())
|
if (!multiPart->parts[a].d->reset())
|
||||||
return false;
|
return false;
|
||||||
|
@ -604,14 +604,21 @@ void QHttpNetworkConnectionChannel::handleStatus()
|
|||||||
case 302:
|
case 302:
|
||||||
case 303:
|
case 303:
|
||||||
case 305:
|
case 305:
|
||||||
case 307: {
|
case 307:
|
||||||
|
case 308: {
|
||||||
// Parse the response headers and get the "location" url
|
// Parse the response headers and get the "location" url
|
||||||
QUrl redirectUrl = connection->d_func()->parseRedirectResponse(socket, reply);
|
QUrl redirectUrl = connection->d_func()->parseRedirectResponse(socket, reply);
|
||||||
if (redirectUrl.isValid())
|
if (redirectUrl.isValid())
|
||||||
reply->setRedirectUrl(redirectUrl);
|
reply->setRedirectUrl(redirectUrl);
|
||||||
|
|
||||||
if (qobject_cast<QHttpNetworkConnection *>(connection))
|
if ((statusCode == 307 || statusCode == 308) && !resetUploadData()) {
|
||||||
|
// Couldn't reset the upload data, which means it will be unable to POST the data -
|
||||||
|
// this would lead to a long wait until it eventually failed and then retried.
|
||||||
|
// Instead of doing that we fail here instead, resetUploadData will already have emitted
|
||||||
|
// a ContentReSendError, so we're done.
|
||||||
|
} else if (qobject_cast<QHttpNetworkConnection *>(connection)) {
|
||||||
QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection);
|
QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 401: // auth required
|
case 401: // auth required
|
||||||
|
@ -96,7 +96,7 @@ void QHttpNetworkReply::setRedirectUrl(const QUrl &url)
|
|||||||
bool QHttpNetworkReply::isHttpRedirect(int statusCode)
|
bool QHttpNetworkReply::isHttpRedirect(int statusCode)
|
||||||
{
|
{
|
||||||
return (statusCode == 301 || statusCode == 302 || statusCode == 303
|
return (statusCode == 301 || statusCode == 302 || statusCode == 303
|
||||||
|| statusCode == 305 || statusCode == 307);
|
|| statusCode == 305 || statusCode == 307 || statusCode == 308);
|
||||||
}
|
}
|
||||||
|
|
||||||
qint64 QHttpNetworkReply::contentLength() const
|
qint64 QHttpNetworkReply::contentLength() const
|
||||||
|
@ -140,7 +140,7 @@ void QNetworkCookieJar::setAllCookies(const QList<QNetworkCookie> &cookieList)
|
|||||||
|
|
||||||
static inline bool isParentPath(const QString &path, const QString &reference)
|
static inline bool isParentPath(const QString &path, const QString &reference)
|
||||||
{
|
{
|
||||||
if (path.startsWith(reference)) {
|
if ((path.isEmpty() && reference == QLatin1String("/")) || path.startsWith(reference)) {
|
||||||
//The cookie-path and the request-path are identical.
|
//The cookie-path and the request-path are identical.
|
||||||
if (path.length() == reference.length())
|
if (path.length() == reference.length())
|
||||||
return true;
|
return true;
|
||||||
|
@ -297,7 +297,7 @@ QNetworkReplyPrivate::QNetworkReplyPrivate()
|
|||||||
|
|
||||||
This signal is emitted if the QNetworkRequest::FollowRedirectsAttribute was
|
This signal is emitted if the QNetworkRequest::FollowRedirectsAttribute was
|
||||||
set in the request and the server responded with a 3xx status (specifically
|
set in the request and the server responded with a 3xx status (specifically
|
||||||
301, 302, 303, 305 or 307 status code) with a valid url in the location
|
301, 302, 303, 305, 307 or 308 status code) with a valid url in the location
|
||||||
header, indicating a HTTP redirect. The \a url parameter contains the new
|
header, indicating a HTTP redirect. The \a url parameter contains the new
|
||||||
redirect url as returned by the server in the location header.
|
redirect url as returned by the server in the location header.
|
||||||
|
|
||||||
|
@ -165,6 +165,16 @@ static QHash<QByteArray, QByteArray> parseHttpOptionHeader(const QByteArray &hea
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if QT_CONFIG(bearermanagement)
|
||||||
|
static bool isSessionNeeded(const QUrl &url)
|
||||||
|
{
|
||||||
|
// Connections to the local machine does not require a session
|
||||||
|
QString host = url.host().toLower();
|
||||||
|
return !QHostAddress(host).isLoopback() && host != QLatin1String("localhost")
|
||||||
|
&& host != QSysInfo::machineHostName().toLower();
|
||||||
|
}
|
||||||
|
#endif // bearer management
|
||||||
|
|
||||||
QNetworkReplyHttpImpl::QNetworkReplyHttpImpl(QNetworkAccessManager* const manager,
|
QNetworkReplyHttpImpl::QNetworkReplyHttpImpl(QNetworkAccessManager* const manager,
|
||||||
const QNetworkRequest& request,
|
const QNetworkRequest& request,
|
||||||
QNetworkAccessManager::Operation& operation,
|
QNetworkAccessManager::Operation& operation,
|
||||||
@ -1115,10 +1125,15 @@ QNetworkAccessManager::Operation QNetworkReplyHttpImplPrivate::getRedirectOperat
|
|||||||
switch (currentOp) {
|
switch (currentOp) {
|
||||||
case QNetworkAccessManager::HeadOperation:
|
case QNetworkAccessManager::HeadOperation:
|
||||||
return QNetworkAccessManager::HeadOperation;
|
return QNetworkAccessManager::HeadOperation;
|
||||||
|
case QNetworkAccessManager::PostOperation:
|
||||||
|
// We MUST keep using POST when being redirected with 307 or 308.
|
||||||
|
if (statusCode == 307 || statusCode == 308)
|
||||||
|
return QNetworkAccessManager::PostOperation;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// For now, we're always returning GET for anything other than HEAD
|
// Use GET for everything else.
|
||||||
return QNetworkAccessManager::GetOperation;
|
return QNetworkAccessManager::GetOperation;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1193,11 +1208,30 @@ void QNetworkReplyHttpImplPrivate::followRedirect()
|
|||||||
{
|
{
|
||||||
Q_Q(QNetworkReplyHttpImpl);
|
Q_Q(QNetworkReplyHttpImpl);
|
||||||
|
|
||||||
|
rawHeaders.clear();
|
||||||
cookedHeaders.clear();
|
cookedHeaders.clear();
|
||||||
|
|
||||||
if (managerPrivate->thread)
|
if (managerPrivate->thread)
|
||||||
managerPrivate->thread->disconnect();
|
managerPrivate->thread->disconnect();
|
||||||
|
|
||||||
|
#if QT_CONFIG(bearermanagement)
|
||||||
|
// If the original request didn't need a session (i.e. it was to localhost)
|
||||||
|
// then we might not have a session open, to which to redirect, if the
|
||||||
|
// new URL is remote. When this happens, we need to open the session now:
|
||||||
|
if (managerPrivate && isSessionNeeded(url)) {
|
||||||
|
if (auto session = managerPrivate->getNetworkSession()) {
|
||||||
|
if (session->state() != QNetworkSession::State::Connected || !session->isOpen()) {
|
||||||
|
startWaitForSession(session);
|
||||||
|
// Need to set 'request' to the redirectRequest so that when QNAM restarts
|
||||||
|
// the request after the session starts it will not repeat the previous request.
|
||||||
|
request = redirectRequest;
|
||||||
|
// Return now, QNAM will start the request when the session has started.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // bearer management
|
||||||
|
|
||||||
QMetaObject::invokeMethod(q, "start", Qt::QueuedConnection,
|
QMetaObject::invokeMethod(q, "start", Qt::QueuedConnection,
|
||||||
Q_ARG(QNetworkRequest, redirectRequest));
|
Q_ARG(QNetworkRequest, redirectRequest));
|
||||||
}
|
}
|
||||||
@ -1210,6 +1244,7 @@ void QNetworkReplyHttpImplPrivate::checkForRedirect(const int statusCode)
|
|||||||
case 302: // Found
|
case 302: // Found
|
||||||
case 303: // See Other
|
case 303: // See Other
|
||||||
case 307: // Temporary Redirect
|
case 307: // Temporary Redirect
|
||||||
|
case 308: // Permanent Redirect
|
||||||
// What do we do about the caching of the HTML note?
|
// What do we do about the caching of the HTML note?
|
||||||
// The response to a 303 MUST NOT be cached, while the response to
|
// The response to a 303 MUST NOT be cached, while the response to
|
||||||
// all of the others is cacheable if the headers indicate it to be
|
// all of the others is cacheable if the headers indicate it to be
|
||||||
@ -1783,10 +1818,8 @@ bool QNetworkReplyHttpImplPrivate::start(const QNetworkRequest &newHttpRequest)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This is not ideal.
|
// This is not ideal.
|
||||||
const QString host = url.host();
|
if (!isSessionNeeded(url)) {
|
||||||
if (host == QLatin1String("localhost") ||
|
// Don't need to check for an open session if we don't need one.
|
||||||
QHostAddress(host).isLoopback()) {
|
|
||||||
// Don't need an open session for localhost access.
|
|
||||||
postRequest(newHttpRequest);
|
postRequest(newHttpRequest);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1810,6 +1843,34 @@ bool QNetworkReplyHttpImplPrivate::start(const QNetworkRequest &newHttpRequest)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if QT_CONFIG(bearermanagement)
|
||||||
|
bool QNetworkReplyHttpImplPrivate::startWaitForSession(QSharedPointer<QNetworkSession> &session)
|
||||||
|
{
|
||||||
|
Q_Q(QNetworkReplyHttpImpl);
|
||||||
|
state = WaitingForSession;
|
||||||
|
|
||||||
|
if (session) {
|
||||||
|
QObject::connect(session.data(), SIGNAL(error(QNetworkSession::SessionError)),
|
||||||
|
q, SLOT(_q_networkSessionFailed()), Qt::QueuedConnection);
|
||||||
|
|
||||||
|
if (!session->isOpen()) {
|
||||||
|
QVariant isBackground = request.attribute(QNetworkRequest::BackgroundRequestAttribute,
|
||||||
|
QVariant::fromValue(false));
|
||||||
|
session->setSessionProperty(QStringLiteral("ConnectInBackground"), isBackground);
|
||||||
|
session->open();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
const Qt::ConnectionType connection = synchronous ? Qt::DirectConnection : Qt::QueuedConnection;
|
||||||
|
qWarning("Backend is waiting for QNetworkSession to connect, but there is none!");
|
||||||
|
QMetaObject::invokeMethod(q, "_q_error", connection,
|
||||||
|
Q_ARG(QNetworkReply::NetworkError, QNetworkReply::NetworkSessionFailedError),
|
||||||
|
Q_ARG(QString, QCoreApplication::translate("QNetworkReply", "Network session error.")));
|
||||||
|
QMetaObject::invokeMethod(q, "_q_finished", connection);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif // QT_CONFIG(bearermanagement)
|
||||||
|
|
||||||
void QNetworkReplyHttpImplPrivate::_q_startOperation()
|
void QNetworkReplyHttpImplPrivate::_q_startOperation()
|
||||||
{
|
{
|
||||||
Q_Q(QNetworkReplyHttpImpl);
|
Q_Q(QNetworkReplyHttpImpl);
|
||||||
@ -1837,24 +1898,8 @@ void QNetworkReplyHttpImplPrivate::_q_startOperation()
|
|||||||
// backend failed to start because the session state is not Connected.
|
// backend failed to start because the session state is not Connected.
|
||||||
// QNetworkAccessManager will call reply->backend->start() again for us when the session
|
// QNetworkAccessManager will call reply->backend->start() again for us when the session
|
||||||
// state changes.
|
// state changes.
|
||||||
state = WaitingForSession;
|
if (!startWaitForSession(session))
|
||||||
|
|
||||||
if (session) {
|
|
||||||
QObject::connect(session.data(), SIGNAL(error(QNetworkSession::SessionError)),
|
|
||||||
q, SLOT(_q_networkSessionFailed()), Qt::QueuedConnection);
|
|
||||||
|
|
||||||
if (!session->isOpen()) {
|
|
||||||
session->setSessionProperty(QStringLiteral("ConnectInBackground"), isBackground);
|
|
||||||
session->open();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
qWarning("Backend is waiting for QNetworkSession to connect, but there is none!");
|
|
||||||
QMetaObject::invokeMethod(q, "_q_error", synchronous ? Qt::DirectConnection : Qt::QueuedConnection,
|
|
||||||
Q_ARG(QNetworkReply::NetworkError, QNetworkReply::NetworkSessionFailedError),
|
|
||||||
Q_ARG(QString, QCoreApplication::translate("QNetworkReply", "Network session error.")));
|
|
||||||
QMetaObject::invokeMethod(q, "_q_finished", synchronous ? Qt::DirectConnection : Qt::QueuedConnection);
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
} else if (session) {
|
} else if (session) {
|
||||||
QObject::connect(session.data(), SIGNAL(stateChanged(QNetworkSession::State)),
|
QObject::connect(session.data(), SIGNAL(stateChanged(QNetworkSession::State)),
|
||||||
q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State)),
|
q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State)),
|
||||||
|
@ -161,6 +161,10 @@ signals:
|
|||||||
|
|
||||||
class QNetworkReplyHttpImplPrivate: public QNetworkReplyPrivate
|
class QNetworkReplyHttpImplPrivate: public QNetworkReplyPrivate
|
||||||
{
|
{
|
||||||
|
#if QT_CONFIG(bearermanagement)
|
||||||
|
bool startWaitForSession(QSharedPointer<QNetworkSession> &session);
|
||||||
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static QHttpNetworkRequest::Priority convert(const QNetworkRequest::Priority& prio);
|
static QHttpNetworkRequest::Priority convert(const QNetworkRequest::Priority& prio);
|
||||||
|
@ -89,31 +89,6 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
"tests": {
|
"tests": {
|
||||||
"getaddrinfo": {
|
|
||||||
"label": "getaddrinfo()",
|
|
||||||
"type": "compile",
|
|
||||||
"test": {
|
|
||||||
"head": [
|
|
||||||
"#include <stdio.h>",
|
|
||||||
"#include <stdlib.h>",
|
|
||||||
"#ifdef __MINGW32__",
|
|
||||||
"# include <winsock2.h>",
|
|
||||||
"# include <ws2tcpip.h>",
|
|
||||||
"#else",
|
|
||||||
"# include <sys/types.h>",
|
|
||||||
"# include <sys/socket.h>",
|
|
||||||
"# include <netdb.h>",
|
|
||||||
"#endif"
|
|
||||||
],
|
|
||||||
"main": [
|
|
||||||
"addrinfo *res = 0;",
|
|
||||||
"(void) getaddrinfo(\"foo\", 0, 0, &res);",
|
|
||||||
"freeaddrinfo(res);",
|
|
||||||
"gai_strerror(0);"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"use": "network"
|
|
||||||
},
|
|
||||||
"getifaddrs": {
|
"getifaddrs": {
|
||||||
"label": "getifaddrs()",
|
"label": "getifaddrs()",
|
||||||
"type": "compile",
|
"type": "compile",
|
||||||
@ -170,11 +145,6 @@
|
|||||||
"emitIf": "config.darwin",
|
"emitIf": "config.darwin",
|
||||||
"output": [ "feature", "privateFeature" ]
|
"output": [ "feature", "privateFeature" ]
|
||||||
},
|
},
|
||||||
"getaddrinfo": {
|
|
||||||
"label": "getaddrinfo()",
|
|
||||||
"condition": "tests.getaddrinfo",
|
|
||||||
"output": [ "feature" ]
|
|
||||||
},
|
|
||||||
"getifaddrs": {
|
"getifaddrs": {
|
||||||
"label": "getifaddrs()",
|
"label": "getifaddrs()",
|
||||||
"condition": "tests.getifaddrs",
|
"condition": "tests.getifaddrs",
|
||||||
@ -337,7 +307,7 @@ For example:
|
|||||||
"args": "corewlan",
|
"args": "corewlan",
|
||||||
"condition": "config.darwin"
|
"condition": "config.darwin"
|
||||||
},
|
},
|
||||||
"getaddrinfo", "getifaddrs", "ipv6ifname", "libproxy",
|
"getifaddrs", "ipv6ifname", "libproxy",
|
||||||
{
|
{
|
||||||
"type": "feature",
|
"type": "feature",
|
||||||
"args": "securetransport",
|
"args": "securetransport",
|
||||||
|
@ -49,8 +49,6 @@ win32: {
|
|||||||
SOURCES += kernel/qdnslookup_win.cpp \
|
SOURCES += kernel/qdnslookup_win.cpp \
|
||||||
kernel/qnetworkinterface_win.cpp
|
kernel/qnetworkinterface_win.cpp
|
||||||
LIBS_PRIVATE += -ldnsapi -liphlpapi
|
LIBS_PRIVATE += -ldnsapi -liphlpapi
|
||||||
DEFINES += WINVER=0x0600 _WIN32_WINNT=0x0600
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
SOURCES += kernel/qdnslookup_winrt.cpp \
|
SOURCES += kernel/qdnslookup_winrt.cpp \
|
||||||
kernel/qnetworkinterface_winrt.cpp
|
kernel/qnetworkinterface_winrt.cpp
|
||||||
|
@ -533,49 +533,6 @@ QHostAddress::QHostAddress(SpecialAddress address)
|
|||||||
setAddress(address);
|
setAddress(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
\overload
|
|
||||||
\since 5.8
|
|
||||||
|
|
||||||
Sets the special address specified by \a address.
|
|
||||||
*/
|
|
||||||
void QHostAddress::setAddress(SpecialAddress address)
|
|
||||||
{
|
|
||||||
d->clear();
|
|
||||||
|
|
||||||
Q_IPV6ADDR ip6;
|
|
||||||
memset(&ip6, 0, sizeof ip6);
|
|
||||||
quint32 ip4 = INADDR_ANY;
|
|
||||||
|
|
||||||
switch (address) {
|
|
||||||
case Null:
|
|
||||||
return;
|
|
||||||
|
|
||||||
case Broadcast:
|
|
||||||
ip4 = INADDR_BROADCAST;
|
|
||||||
break;
|
|
||||||
case LocalHost:
|
|
||||||
ip4 = INADDR_LOOPBACK;
|
|
||||||
break;
|
|
||||||
case AnyIPv4:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LocalHostIPv6:
|
|
||||||
ip6[15] = 1;
|
|
||||||
Q_FALLTHROUGH();
|
|
||||||
case AnyIPv6:
|
|
||||||
d->setAddress(ip6);
|
|
||||||
return;
|
|
||||||
|
|
||||||
case Any:
|
|
||||||
d->protocol = QAbstractSocket::AnyIPProtocol;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// common IPv4 part
|
|
||||||
d->setAddress(ip4);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Destroys the host address object.
|
Destroys the host address object.
|
||||||
*/
|
*/
|
||||||
@ -739,6 +696,49 @@ void QHostAddress::setAddress(const struct sockaddr *sockaddr)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\overload
|
||||||
|
\since 5.8
|
||||||
|
|
||||||
|
Sets the special address specified by \a address.
|
||||||
|
*/
|
||||||
|
void QHostAddress::setAddress(SpecialAddress address)
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
|
||||||
|
Q_IPV6ADDR ip6;
|
||||||
|
memset(&ip6, 0, sizeof ip6);
|
||||||
|
quint32 ip4 = INADDR_ANY;
|
||||||
|
|
||||||
|
switch (address) {
|
||||||
|
case Null:
|
||||||
|
return;
|
||||||
|
|
||||||
|
case Broadcast:
|
||||||
|
ip4 = INADDR_BROADCAST;
|
||||||
|
break;
|
||||||
|
case LocalHost:
|
||||||
|
ip4 = INADDR_LOOPBACK;
|
||||||
|
break;
|
||||||
|
case AnyIPv4:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LocalHostIPv6:
|
||||||
|
ip6[15] = 1;
|
||||||
|
Q_FALLTHROUGH();
|
||||||
|
case AnyIPv6:
|
||||||
|
d->setAddress(ip6);
|
||||||
|
return;
|
||||||
|
|
||||||
|
case Any:
|
||||||
|
d->protocol = QAbstractSocket::AnyIPProtocol;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// common IPv4 part
|
||||||
|
d->setAddress(ip4);
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Returns the IPv4 address as a number.
|
Returns the IPv4 address as a number.
|
||||||
|
|
||||||
|
@ -66,10 +66,6 @@
|
|||||||
# include <gnu/lib-names.h>
|
# include <gnu/lib-names.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined (QT_NO_GETADDRINFO)
|
|
||||||
static QBasicMutex getHostByNameMutex;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
// Almost always the same. If not, specify in qplatformdefs.h.
|
// Almost always the same. If not, specify in qplatformdefs.h.
|
||||||
@ -188,7 +184,6 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName)
|
|||||||
QHostAddress address;
|
QHostAddress address;
|
||||||
if (address.setAddress(hostName)) {
|
if (address.setAddress(hostName)) {
|
||||||
// Reverse lookup
|
// Reverse lookup
|
||||||
#if !defined (QT_NO_GETADDRINFO)
|
|
||||||
sockaddr_in sa4;
|
sockaddr_in sa4;
|
||||||
sockaddr_in6 sa6;
|
sockaddr_in6 sa6;
|
||||||
sockaddr *sa = 0;
|
sockaddr *sa = 0;
|
||||||
@ -211,12 +206,6 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName)
|
|||||||
char hbuf[NI_MAXHOST];
|
char hbuf[NI_MAXHOST];
|
||||||
if (sa && getnameinfo(sa, saSize, hbuf, sizeof(hbuf), 0, 0, 0) == 0)
|
if (sa && getnameinfo(sa, saSize, hbuf, sizeof(hbuf), 0, 0, 0) == 0)
|
||||||
results.setHostName(QString::fromLatin1(hbuf));
|
results.setHostName(QString::fromLatin1(hbuf));
|
||||||
#else
|
|
||||||
in_addr_t inetaddr = qt_safe_inet_addr(hostName.toLatin1().constData());
|
|
||||||
struct hostent *ent = gethostbyaddr((const char *)&inetaddr, sizeof(inetaddr), AF_INET);
|
|
||||||
if (ent)
|
|
||||||
results.setHostName(QString::fromLatin1(ent->h_name));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (results.hostName().isEmpty())
|
if (results.hostName().isEmpty())
|
||||||
results.setHostName(address.toString());
|
results.setHostName(address.toString());
|
||||||
@ -235,7 +224,6 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName)
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined (QT_NO_GETADDRINFO)
|
|
||||||
// Call getaddrinfo, and place all IPv4 addresses at the start and
|
// Call getaddrinfo, and place all IPv4 addresses at the start and
|
||||||
// the IPv6 addresses at the end of the address list in results.
|
// the IPv6 addresses at the end of the address list in results.
|
||||||
addrinfo *res = 0;
|
addrinfo *res = 0;
|
||||||
@ -302,39 +290,6 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName)
|
|||||||
results.setErrorString(QString::fromLocal8Bit(gai_strerror(result)));
|
results.setErrorString(QString::fromLocal8Bit(gai_strerror(result)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
|
||||||
// Fall back to gethostbyname for platforms that don't define
|
|
||||||
// getaddrinfo. gethostbyname does not support IPv6, and it's not
|
|
||||||
// reentrant on all platforms. For now this is okay since we only
|
|
||||||
// use one QHostInfoAgent, but if more agents are introduced, locking
|
|
||||||
// must be provided.
|
|
||||||
QMutexLocker locker(&getHostByNameMutex);
|
|
||||||
hostent *result = gethostbyname(aceHostname.constData());
|
|
||||||
if (result) {
|
|
||||||
if (result->h_addrtype == AF_INET) {
|
|
||||||
QList<QHostAddress> addresses;
|
|
||||||
for (char **p = result->h_addr_list; *p != 0; p++) {
|
|
||||||
QHostAddress addr;
|
|
||||||
addr.setAddress(ntohl(*((quint32 *)*p)));
|
|
||||||
if (!addresses.contains(addr))
|
|
||||||
addresses.prepend(addr);
|
|
||||||
}
|
|
||||||
results.setAddresses(addresses);
|
|
||||||
} else {
|
|
||||||
results.setError(QHostInfo::UnknownError);
|
|
||||||
results.setErrorString(tr("Unknown address type"));
|
|
||||||
}
|
|
||||||
#if !defined(Q_OS_VXWORKS)
|
|
||||||
} else if (h_errno == HOST_NOT_FOUND || h_errno == NO_DATA
|
|
||||||
|| h_errno == NO_ADDRESS) {
|
|
||||||
results.setError(QHostInfo::HostNotFound);
|
|
||||||
results.setErrorString(tr("Host not found"));
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
results.setError(QHostInfo::UnknownError);
|
|
||||||
results.setErrorString(tr("Unknown error"));
|
|
||||||
}
|
|
||||||
#endif // !defined (QT_NO_GETADDRINFO)
|
|
||||||
|
|
||||||
#if defined(QHOSTINFO_DEBUG)
|
#if defined(QHOSTINFO_DEBUG)
|
||||||
if (results.error() != QHostInfo::NoError) {
|
if (results.error() != QHostInfo::NoError) {
|
||||||
@ -377,11 +332,6 @@ QString QHostInfo::localDomainName()
|
|||||||
if (local_res_init && local_res) {
|
if (local_res_init && local_res) {
|
||||||
// using thread-unsafe version
|
// using thread-unsafe version
|
||||||
|
|
||||||
#if defined(QT_NO_GETADDRINFO)
|
|
||||||
// We have to call res_init to be sure that _res was initialized
|
|
||||||
// So, for systems without getaddrinfo (which is thread-safe), we lock the mutex too
|
|
||||||
QMutexLocker locker(&getHostByNameMutex);
|
|
||||||
#endif
|
|
||||||
local_res_init();
|
local_res_init();
|
||||||
QString domainName = QUrl::fromAce(local_res->defdname);
|
QString domainName = QUrl::fromAce(local_res->defdname);
|
||||||
if (domainName.isEmpty())
|
if (domainName.isEmpty())
|
||||||
|
@ -50,50 +50,12 @@ QT_BEGIN_NAMESPACE
|
|||||||
|
|
||||||
//#define QHOSTINFO_DEBUG
|
//#define QHOSTINFO_DEBUG
|
||||||
|
|
||||||
// Older SDKs do not include the addrinfo struct declaration, so we
|
|
||||||
// include a copy of it here.
|
|
||||||
struct qt_addrinfo
|
|
||||||
{
|
|
||||||
int ai_flags;
|
|
||||||
int ai_family;
|
|
||||||
int ai_socktype;
|
|
||||||
int ai_protocol;
|
|
||||||
size_t ai_addrlen;
|
|
||||||
char *ai_canonname;
|
|
||||||
sockaddr *ai_addr;
|
|
||||||
qt_addrinfo *ai_next;
|
|
||||||
};
|
|
||||||
|
|
||||||
//###
|
//###
|
||||||
#define QT_SOCKLEN_T int
|
#define QT_SOCKLEN_T int
|
||||||
#ifndef NI_MAXHOST // already defined to 1025 in ws2tcpip.h?
|
#ifndef NI_MAXHOST // already defined to 1025 in ws2tcpip.h?
|
||||||
#define NI_MAXHOST 1024
|
#define NI_MAXHOST 1024
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef int (__stdcall *getnameinfoProto)(const sockaddr *, QT_SOCKLEN_T, const char *, DWORD, const char *, DWORD, int);
|
|
||||||
typedef int (__stdcall *getaddrinfoProto)(const char *, const char *, const qt_addrinfo *, qt_addrinfo **);
|
|
||||||
typedef int (__stdcall *freeaddrinfoProto)(qt_addrinfo *);
|
|
||||||
static getnameinfoProto local_getnameinfo = 0;
|
|
||||||
static getaddrinfoProto local_getaddrinfo = 0;
|
|
||||||
static freeaddrinfoProto local_freeaddrinfo = 0;
|
|
||||||
|
|
||||||
static bool resolveLibraryInternal()
|
|
||||||
{
|
|
||||||
// Attempt to resolve getaddrinfo(); without it we'll have to fall
|
|
||||||
// back to gethostbyname(), which has no IPv6 support.
|
|
||||||
#if defined (Q_OS_WINRT)
|
|
||||||
local_getaddrinfo = (getaddrinfoProto) &getaddrinfo;
|
|
||||||
local_freeaddrinfo = (freeaddrinfoProto) &freeaddrinfo;
|
|
||||||
local_getnameinfo = (getnameinfoProto) getnameinfo;
|
|
||||||
#else
|
|
||||||
local_getaddrinfo = (getaddrinfoProto) QSystemLibrary::resolve(QLatin1String("ws2_32"), "getaddrinfo");
|
|
||||||
local_freeaddrinfo = (freeaddrinfoProto) QSystemLibrary::resolve(QLatin1String("ws2_32"), "freeaddrinfo");
|
|
||||||
local_getnameinfo = (getnameinfoProto) QSystemLibrary::resolve(QLatin1String("ws2_32"), "getnameinfo");
|
|
||||||
#endif
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
Q_GLOBAL_STATIC_WITH_ARGS(bool, resolveLibrary, (resolveLibraryInternal()))
|
|
||||||
|
|
||||||
static void translateWSAError(int error, QHostInfo *results)
|
static void translateWSAError(int error, QHostInfo *results)
|
||||||
{
|
{
|
||||||
switch (error) {
|
switch (error) {
|
||||||
@ -114,21 +76,17 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName)
|
|||||||
{
|
{
|
||||||
QSysInfo::machineHostName(); // this initializes ws2_32.dll
|
QSysInfo::machineHostName(); // this initializes ws2_32.dll
|
||||||
|
|
||||||
// Load res_init on demand.
|
|
||||||
resolveLibrary();
|
|
||||||
|
|
||||||
QHostInfo results;
|
QHostInfo results;
|
||||||
|
|
||||||
#if defined(QHOSTINFO_DEBUG)
|
#if defined(QHOSTINFO_DEBUG)
|
||||||
qDebug("QHostInfoAgent::fromName(): looking up \"%s\" (IPv6 support is %s)",
|
qDebug("QHostInfoAgent::fromName(): looking up \"%s\" (IPv6 support is %s)",
|
||||||
hostName.toLatin1().constData(),
|
hostName.toLatin1().constData(),
|
||||||
(local_getaddrinfo && local_freeaddrinfo) ? "enabled" : "disabled");
|
(getaddrinfo && freeaddrinfo) ? "enabled" : "disabled");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QHostAddress address;
|
QHostAddress address;
|
||||||
if (address.setAddress(hostName)) {
|
if (address.setAddress(hostName)) {
|
||||||
// Reverse lookup
|
// Reverse lookup
|
||||||
if (local_getnameinfo) {
|
|
||||||
sockaddr_in sa4;
|
sockaddr_in sa4;
|
||||||
sockaddr_in6 sa6;
|
sockaddr_in6 sa6;
|
||||||
sockaddr *sa;
|
sockaddr *sa;
|
||||||
@ -148,14 +106,8 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName)
|
|||||||
}
|
}
|
||||||
|
|
||||||
char hbuf[NI_MAXHOST];
|
char hbuf[NI_MAXHOST];
|
||||||
if (local_getnameinfo(sa, saSize, hbuf, sizeof(hbuf), 0, 0, 0) == 0)
|
if (getnameinfo(sa, saSize, hbuf, sizeof(hbuf), 0, 0, 0) == 0)
|
||||||
results.setHostName(QString::fromLatin1(hbuf));
|
results.setHostName(QString::fromLatin1(hbuf));
|
||||||
} else {
|
|
||||||
unsigned long addr = inet_addr(hostName.toLatin1().constData());
|
|
||||||
struct hostent *ent = gethostbyaddr((const char*)&addr, sizeof(addr), AF_INET);
|
|
||||||
if (ent)
|
|
||||||
results.setHostName(QString::fromLatin1(ent->h_name));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (results.hostName().isEmpty())
|
if (results.hostName().isEmpty())
|
||||||
results.setHostName(address.toString());
|
results.setHostName(address.toString());
|
||||||
@ -172,15 +124,11 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName)
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (local_getaddrinfo && local_freeaddrinfo) {
|
addrinfo *res;
|
||||||
// Call getaddrinfo, and place all IPv4 addresses at the start
|
int err = getaddrinfo(aceHostname.constData(), 0, 0, &res);
|
||||||
// and the IPv6 addresses at the end of the address list in
|
|
||||||
// results.
|
|
||||||
qt_addrinfo *res;
|
|
||||||
int err = local_getaddrinfo(aceHostname.constData(), 0, 0, &res);
|
|
||||||
if (err == 0) {
|
if (err == 0) {
|
||||||
QList<QHostAddress> addresses;
|
QList<QHostAddress> addresses;
|
||||||
for (qt_addrinfo *p = res; p != 0; p = p->ai_next) {
|
for (addrinfo *p = res; p != 0; p = p->ai_next) {
|
||||||
switch (p->ai_family) {
|
switch (p->ai_family) {
|
||||||
case AF_INET: {
|
case AF_INET: {
|
||||||
QHostAddress addr;
|
QHostAddress addr;
|
||||||
@ -202,35 +150,10 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
results.setAddresses(addresses);
|
results.setAddresses(addresses);
|
||||||
local_freeaddrinfo(res);
|
freeaddrinfo(res);
|
||||||
} else {
|
} else {
|
||||||
translateWSAError(WSAGetLastError(), &results);
|
translateWSAError(WSAGetLastError(), &results);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// Fall back to gethostbyname, which only supports IPv4.
|
|
||||||
hostent *ent = gethostbyname(aceHostname.constData());
|
|
||||||
if (ent) {
|
|
||||||
char **p;
|
|
||||||
QList<QHostAddress> addresses;
|
|
||||||
switch (ent->h_addrtype) {
|
|
||||||
case AF_INET:
|
|
||||||
for (p = ent->h_addr_list; *p != 0; p++) {
|
|
||||||
long *ip4Addr = (long *) *p;
|
|
||||||
QHostAddress temp;
|
|
||||||
temp.setAddress(ntohl(*ip4Addr));
|
|
||||||
addresses << temp;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
results.setError(QHostInfo::UnknownError);
|
|
||||||
results.setErrorString(tr("Unknown address type"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
results.setAddresses(addresses);
|
|
||||||
} else {
|
|
||||||
translateWSAError(WSAGetLastError(), &results);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(QHOSTINFO_DEBUG)
|
#if defined(QHOSTINFO_DEBUG)
|
||||||
if (results.error() != QHostInfo::NoError) {
|
if (results.error() != QHostInfo::NoError) {
|
||||||
|
@ -124,9 +124,7 @@ QT_BEGIN_NAMESPACE
|
|||||||
\row \li Linux \li Supported \li Supported \li Supported
|
\row \li Linux \li Supported \li Supported \li Supported
|
||||||
\row \li OS X \li Supported \li Supported \li Only for IPv6
|
\row \li OS X \li Supported \li Supported \li Only for IPv6
|
||||||
\row \li Other Unix supporting RFC 3542 \li Only for IPv6 \li Only for IPv6 \li Only for IPv6
|
\row \li Other Unix supporting RFC 3542 \li Only for IPv6 \li Only for IPv6 \li Only for IPv6
|
||||||
\row \li Windows XP and older \li Not supported \li Not supported \li Not supported
|
\row \li Windows (desktop) \li Supported \li Supported \li Supported
|
||||||
\row \li Windows Vista & up \li Supported \li Supported \li Supported
|
|
||||||
\row \li Windows CE \li Not supported \li Not supported \li Not supported
|
|
||||||
\row \li Windows RT \li Not supported \li Not supported \li Not supported
|
\row \li Windows RT \li Not supported \li Not supported \li Not supported
|
||||||
\endtable
|
\endtable
|
||||||
|
|
||||||
|
@ -56,6 +56,7 @@
|
|||||||
// (http://sourceforge.net/p/mingw-w64/mailman/message/32935366/)
|
// (http://sourceforge.net/p/mingw-w64/mailman/message/32935366/)
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#include <ws2ipdef.h>
|
#include <ws2ipdef.h>
|
||||||
|
#include <wincrypt.h>
|
||||||
#include <iphlpapi.h>
|
#include <iphlpapi.h>
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
|
|
||||||
|
@ -174,16 +174,6 @@ static inline int qt_safe_ioctl(int sockfd, unsigned long request, T arg)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// VxWorks' headers do not specify any const modifiers
|
|
||||||
static inline in_addr_t qt_safe_inet_addr(const char *cp)
|
|
||||||
{
|
|
||||||
#ifdef Q_OS_VXWORKS
|
|
||||||
return ::inet_addr((char *) cp);
|
|
||||||
#else
|
|
||||||
return ::inet_addr(cp);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int qt_safe_sendmsg(int sockfd, const struct msghdr *msg, int flags)
|
static inline int qt_safe_sendmsg(int sockfd, const struct msghdr *msg, int flags)
|
||||||
{
|
{
|
||||||
#ifdef MSG_NOSIGNAL
|
#ifdef MSG_NOSIGNAL
|
||||||
|
@ -454,9 +454,11 @@ QNetworkDatagram QUdpSocket::receiveDatagram(qint64 maxSize)
|
|||||||
QAbstractSocketEngine::WantAll);
|
QAbstractSocketEngine::WantAll);
|
||||||
d->hasPendingData = false;
|
d->hasPendingData = false;
|
||||||
d->socketEngine->setReadNotificationEnabled(true);
|
d->socketEngine->setReadNotificationEnabled(true);
|
||||||
if (readBytes < 0)
|
if (readBytes < 0) {
|
||||||
d->setErrorAndEmit(d->socketEngine->error(), d->socketEngine->errorString());
|
d->setErrorAndEmit(d->socketEngine->error(), d->socketEngine->errorString());
|
||||||
else if (readBytes != result.d->data.size())
|
readBytes = 0;
|
||||||
|
}
|
||||||
|
|
||||||
result.d->data.truncate(readBytes);
|
result.d->data.truncate(readBytes);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -92,7 +92,7 @@ EphemeralSecKeychain::EphemeralSecKeychain()
|
|||||||
{
|
{
|
||||||
const auto uuid = QUuid::createUuid();
|
const auto uuid = QUuid::createUuid();
|
||||||
if (uuid.isNull()) {
|
if (uuid.isNull()) {
|
||||||
qCWarning(lcSsl) << "Failed to create an unique keychain name";
|
qCWarning(lcSsl) << "Failed to create a unique keychain name";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -666,7 +666,7 @@ static CTFontUIFontType fontTypeFromTheme(QPlatformTheme::Font f)
|
|||||||
return kCTFontUIFontSystem;
|
return kCTFontUIFontSystem;
|
||||||
|
|
||||||
case QPlatformTheme::TipLabelFont:
|
case QPlatformTheme::TipLabelFont:
|
||||||
return kCTFontToolTipFontType;
|
return kCTFontUIFontToolTip;
|
||||||
|
|
||||||
case QPlatformTheme::StatusBarFont:
|
case QPlatformTheme::StatusBarFont:
|
||||||
return kCTFontUIFontSystem;
|
return kCTFontUIFontSystem;
|
||||||
|
@ -1980,12 +1980,6 @@ QFont QWindowsFontDatabase::systemDefaultFont()
|
|||||||
// long deprecated; the message font of the NONCLIENTMETRICS structure obtained by
|
// long deprecated; the message font of the NONCLIENTMETRICS structure obtained by
|
||||||
// SystemParametersInfo(SPI_GETNONCLIENTMETRICS) should be used instead (see
|
// SystemParametersInfo(SPI_GETNONCLIENTMETRICS) should be used instead (see
|
||||||
// QWindowsTheme::refreshFonts(), typically "Segoe UI, 9pt"), which is larger.
|
// QWindowsTheme::refreshFonts(), typically "Segoe UI, 9pt"), which is larger.
|
||||||
// In single monitor setups, the point sizes revolve around 8 (depending on UI
|
|
||||||
// scale factor, but not proportional to it). However, in multi monitor setups,
|
|
||||||
// where the DPI of the primary monitor are smaller than those of the secondary,
|
|
||||||
// large bogus values are returned. Limit to 8.25 in that case.
|
|
||||||
if (GetSystemMetrics(SM_CMONITORS) > 1 && systemFont.pointSizeF() > 8.25)
|
|
||||||
systemFont.setPointSizeF(8.25);
|
|
||||||
#endif // Qt 5
|
#endif // Qt 5
|
||||||
qCDebug(lcQpaFonts) << __FUNCTION__ << systemFont;
|
qCDebug(lcQpaFonts) << __FUNCTION__ << systemFont;
|
||||||
return systemFont;
|
return systemFont;
|
||||||
|
@ -55,10 +55,10 @@
|
|||||||
|
|
||||||
#if defined(Q_OS_WIN32)
|
#if defined(Q_OS_WIN32)
|
||||||
// PMIB_TCPTABLE2 is only available since Vista
|
// PMIB_TCPTABLE2 is only available since Vista
|
||||||
#if _WIN32_WINNT < 0x0600
|
#if _WIN32_WINNT < 0x0601
|
||||||
# undef _WIN32_WINNT
|
# undef _WIN32_WINNT
|
||||||
# define _WIN32_WINNT 0x0600
|
# define _WIN32_WINNT 0x0601
|
||||||
#endif // _WIN32_WINNT < 0x0600
|
#endif // _WIN32_WINNT < 0x0601
|
||||||
#include "../platformdefs_win.h"
|
#include "../platformdefs_win.h"
|
||||||
#include <iphlpapi.h>
|
#include <iphlpapi.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -45,6 +45,7 @@
|
|||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#include <mswsock.h>
|
#include <mswsock.h>
|
||||||
#undef interface
|
#undef interface
|
||||||
|
#include <wincrypt.h>
|
||||||
#include <winioctl.h>
|
#include <winioctl.h>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
@ -520,7 +520,7 @@ static inline int fromBase8(const char *s, const char *end)
|
|||||||
{
|
{
|
||||||
int result = 0;
|
int result = 0;
|
||||||
while (*s && s != end) {
|
while (*s && s != end) {
|
||||||
if (*s <= '0' || *s >= '7')
|
if (*s < '0' || *s > '7')
|
||||||
return 0;
|
return 0;
|
||||||
result *= 8;
|
result *= 8;
|
||||||
result += *s - '0';
|
result += *s - '0';
|
||||||
|
@ -104,11 +104,11 @@ namespace QtAndroidAccessibility
|
|||||||
static jintArray childIdListForAccessibleObject(JNIEnv *env, jobject /*thiz*/, jint objectId)
|
static jintArray childIdListForAccessibleObject(JNIEnv *env, jobject /*thiz*/, jint objectId)
|
||||||
{
|
{
|
||||||
QAccessibleInterface *iface = interfaceFromId(objectId);
|
QAccessibleInterface *iface = interfaceFromId(objectId);
|
||||||
if (iface) {
|
if (iface && iface->isValid()) {
|
||||||
jintArray jArray = env->NewIntArray(jsize(iface->childCount()));
|
jintArray jArray = env->NewIntArray(jsize(iface->childCount()));
|
||||||
for (int i = 0; i < iface->childCount(); ++i) {
|
for (int i = 0; i < iface->childCount(); ++i) {
|
||||||
QAccessibleInterface *child = iface->child(i);
|
QAccessibleInterface *child = iface->child(i);
|
||||||
if (child) {
|
if (child && child->isValid()) {
|
||||||
QAccessible::Id ifaceId = QAccessible::uniqueId(child);
|
QAccessible::Id ifaceId = QAccessible::uniqueId(child);
|
||||||
jint jid = ifaceId;
|
jint jid = ifaceId;
|
||||||
env->SetIntArrayRegion(jArray, i, 1, &jid);
|
env->SetIntArrayRegion(jArray, i, 1, &jid);
|
||||||
@ -123,9 +123,9 @@ namespace QtAndroidAccessibility
|
|||||||
static jint parentId(JNIEnv */*env*/, jobject /*thiz*/, jint objectId)
|
static jint parentId(JNIEnv */*env*/, jobject /*thiz*/, jint objectId)
|
||||||
{
|
{
|
||||||
QAccessibleInterface *iface = interfaceFromId(objectId);
|
QAccessibleInterface *iface = interfaceFromId(objectId);
|
||||||
if (iface) {
|
if (iface && iface->isValid()) {
|
||||||
QAccessibleInterface *parent = iface->parent();
|
QAccessibleInterface *parent = iface->parent();
|
||||||
if (parent) {
|
if (parent && parent->isValid()) {
|
||||||
if (parent->role() == QAccessible::Application)
|
if (parent->role() == QAccessible::Application)
|
||||||
return -1;
|
return -1;
|
||||||
return QAccessible::uniqueId(parent);
|
return QAccessible::uniqueId(parent);
|
||||||
@ -151,7 +151,7 @@ namespace QtAndroidAccessibility
|
|||||||
static jint hitTest(JNIEnv */*env*/, jobject /*thiz*/, jfloat x, jfloat y)
|
static jint hitTest(JNIEnv */*env*/, jobject /*thiz*/, jfloat x, jfloat y)
|
||||||
{
|
{
|
||||||
QAccessibleInterface *root = interfaceFromId(-1);
|
QAccessibleInterface *root = interfaceFromId(-1);
|
||||||
if (root) {
|
if (root && root->isValid()) {
|
||||||
QPoint pos = QHighDpi::fromNativePixels(QPoint(int(x), int(y)), root->window());
|
QPoint pos = QHighDpi::fromNativePixels(QPoint(int(x), int(y)), root->window());
|
||||||
|
|
||||||
QAccessibleInterface *child = root->childAt(pos.x(), pos.y());
|
QAccessibleInterface *child = root->childAt(pos.x(), pos.y());
|
||||||
@ -170,7 +170,7 @@ namespace QtAndroidAccessibility
|
|||||||
{
|
{
|
||||||
// qDebug() << "A11Y: CLICK: " << objectId;
|
// qDebug() << "A11Y: CLICK: " << objectId;
|
||||||
QAccessibleInterface *iface = interfaceFromId(objectId);
|
QAccessibleInterface *iface = interfaceFromId(objectId);
|
||||||
if (iface && iface->actionInterface()) {
|
if (iface && iface->isValid() && iface->actionInterface()) {
|
||||||
if (iface->actionInterface()->actionNames().contains(QAccessibleActionInterface::pressAction()))
|
if (iface->actionInterface()->actionNames().contains(QAccessibleActionInterface::pressAction()))
|
||||||
iface->actionInterface()->doAction(QAccessibleActionInterface::pressAction());
|
iface->actionInterface()->doAction(QAccessibleActionInterface::pressAction());
|
||||||
else
|
else
|
||||||
@ -182,13 +182,17 @@ namespace QtAndroidAccessibility
|
|||||||
static jboolean scrollForward(JNIEnv */*env*/, jobject /*thiz*/, jint objectId)
|
static jboolean scrollForward(JNIEnv */*env*/, jobject /*thiz*/, jint objectId)
|
||||||
{
|
{
|
||||||
QAccessibleInterface *iface = interfaceFromId(objectId);
|
QAccessibleInterface *iface = interfaceFromId(objectId);
|
||||||
|
if (iface && iface->isValid())
|
||||||
return QAccessibleBridgeUtils::performEffectiveAction(iface, QAccessibleActionInterface::increaseAction());
|
return QAccessibleBridgeUtils::performEffectiveAction(iface, QAccessibleActionInterface::increaseAction());
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static jboolean scrollBackward(JNIEnv */*env*/, jobject /*thiz*/, jint objectId)
|
static jboolean scrollBackward(JNIEnv */*env*/, jobject /*thiz*/, jint objectId)
|
||||||
{
|
{
|
||||||
QAccessibleInterface *iface = interfaceFromId(objectId);
|
QAccessibleInterface *iface = interfaceFromId(objectId);
|
||||||
|
if (iface && iface->isValid())
|
||||||
return QAccessibleBridgeUtils::performEffectiveAction(iface, QAccessibleActionInterface::decreaseAction());
|
return QAccessibleBridgeUtils::performEffectiveAction(iface, QAccessibleActionInterface::decreaseAction());
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -450,6 +450,17 @@ static jboolean startQtAndroidPlugin(JNIEnv* /*env*/, jobject /*object*//*, jobj
|
|||||||
|
|
||||||
static void *startMainMethod(void */*data*/)
|
static void *startMainMethod(void */*data*/)
|
||||||
{
|
{
|
||||||
|
{
|
||||||
|
JNIEnv* env = nullptr;
|
||||||
|
JavaVMAttachArgs args;
|
||||||
|
args.version = JNI_VERSION_1_6;
|
||||||
|
args.name = "QtMainThread";
|
||||||
|
args.group = NULL;
|
||||||
|
JavaVM *vm = QtAndroidPrivate::javaVM();
|
||||||
|
if (vm != 0)
|
||||||
|
vm->AttachCurrentThread(&env, &args);
|
||||||
|
}
|
||||||
|
|
||||||
QVarLengthArray<const char *> params(m_applicationParams.size());
|
QVarLengthArray<const char *> params(m_applicationParams.size());
|
||||||
for (int i = 0; i < m_applicationParams.size(); i++)
|
for (int i = 0; i < m_applicationParams.size(); i++)
|
||||||
params[i] = static_cast<const char *>(m_applicationParams[i].constData());
|
params[i] = static_cast<const char *>(m_applicationParams[i].constData());
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
TARGET = qcocoa
|
TARGET = qcocoa
|
||||||
|
|
||||||
OBJECTIVE_SOURCES += main.mm \
|
SOURCES += main.mm \
|
||||||
qcocoaintegration.mm \
|
qcocoaintegration.mm \
|
||||||
qcocoascreen.mm \
|
qcocoascreen.mm \
|
||||||
qcocoatheme.mm \
|
qcocoatheme.mm \
|
||||||
@ -32,9 +32,8 @@ OBJECTIVE_SOURCES += main.mm \
|
|||||||
qcocoasystemtrayicon.mm \
|
qcocoasystemtrayicon.mm \
|
||||||
qcocoaintrospection.mm \
|
qcocoaintrospection.mm \
|
||||||
qcocoakeymapper.mm \
|
qcocoakeymapper.mm \
|
||||||
qcocoamimetypes.mm
|
qcocoamimetypes.mm \
|
||||||
|
messages.cpp
|
||||||
SOURCES += messages.cpp
|
|
||||||
|
|
||||||
HEADERS += qcocoaintegration.h \
|
HEADERS += qcocoaintegration.h \
|
||||||
qcocoascreen.h \
|
qcocoascreen.h \
|
||||||
@ -70,7 +69,7 @@ HEADERS += qcocoaintegration.h \
|
|||||||
qcocoamimetypes.h
|
qcocoamimetypes.h
|
||||||
|
|
||||||
qtConfig(opengl.*) {
|
qtConfig(opengl.*) {
|
||||||
OBJECTIVE_SOURCES += qcocoaglcontext.mm
|
SOURCES += qcocoaglcontext.mm
|
||||||
|
|
||||||
HEADERS += qcocoaglcontext.h
|
HEADERS += qcocoaglcontext.h
|
||||||
}
|
}
|
||||||
@ -89,7 +88,7 @@ CONFIG += no_app_extension_api_only
|
|||||||
qtHaveModule(widgets) {
|
qtHaveModule(widgets) {
|
||||||
QT_FOR_CONFIG += widgets
|
QT_FOR_CONFIG += widgets
|
||||||
|
|
||||||
OBJECTIVE_SOURCES += \
|
SOURCES += \
|
||||||
qpaintengine_mac.mm \
|
qpaintengine_mac.mm \
|
||||||
qprintengine_mac.mm \
|
qprintengine_mac.mm \
|
||||||
qcocoaprintersupport.mm \
|
qcocoaprintersupport.mm \
|
||||||
|
@ -92,7 +92,6 @@
|
|||||||
|
|
||||||
QT_USE_NAMESPACE
|
QT_USE_NAMESPACE
|
||||||
|
|
||||||
@class QT_MANGLE_NAMESPACE(QNSMenu);
|
|
||||||
@class QT_MANGLE_NAMESPACE(QNSImageView);
|
@class QT_MANGLE_NAMESPACE(QNSImageView);
|
||||||
|
|
||||||
@interface QT_MANGLE_NAMESPACE(QNSStatusItem) : NSObject <NSUserNotificationCenterDelegate>
|
@interface QT_MANGLE_NAMESPACE(QNSStatusItem) : NSObject <NSUserNotificationCenterDelegate>
|
||||||
@ -123,16 +122,8 @@ QT_USE_NAMESPACE
|
|||||||
-(void)mousePressed:(NSEvent *)mouseEvent button:(Qt::MouseButton)mouseButton;
|
-(void)mousePressed:(NSEvent *)mouseEvent button:(Qt::MouseButton)mouseButton;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface QT_MANGLE_NAMESPACE(QNSMenu) : NSMenu <NSMenuDelegate> {
|
|
||||||
QPlatformMenu *qmenu;
|
|
||||||
}
|
|
||||||
-(QPlatformMenu*)menu;
|
|
||||||
-(id)initWithQMenu:(QPlatformMenu*)qmenu;
|
|
||||||
@end
|
|
||||||
|
|
||||||
QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSStatusItem);
|
QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSStatusItem);
|
||||||
QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSImageView);
|
QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSImageView);
|
||||||
QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSMenu);
|
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
class QSystemTrayIconSys
|
class QSystemTrayIconSys
|
||||||
@ -447,26 +438,4 @@ QT_END_NAMESPACE
|
|||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
class QSystemTrayIconQMenu : public QPlatformMenu
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
void doAboutToShow() { emit aboutToShow(); }
|
|
||||||
private:
|
|
||||||
QSystemTrayIconQMenu();
|
|
||||||
};
|
|
||||||
|
|
||||||
@implementation QNSMenu
|
|
||||||
-(id)initWithQMenu:(QPlatformMenu*)qm {
|
|
||||||
self = [super init];
|
|
||||||
if (self) {
|
|
||||||
self->qmenu = qm;
|
|
||||||
[self setDelegate:self];
|
|
||||||
}
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
-(QPlatformMenu*)menu {
|
|
||||||
return qmenu;
|
|
||||||
}
|
|
||||||
@end
|
|
||||||
|
|
||||||
#endif // QT_NO_SYSTEMTRAYICON
|
#endif // QT_NO_SYSTEMTRAYICON
|
||||||
|
@ -55,6 +55,7 @@
|
|||||||
#include <QtGui/private/qguiapplication_p.h>
|
#include <QtGui/private/qguiapplication_p.h>
|
||||||
#include <QtGui/private/qcoregraphics_p.h>
|
#include <QtGui/private/qcoregraphics_p.h>
|
||||||
#include <QtGui/qpainter.h>
|
#include <QtGui/qpainter.h>
|
||||||
|
#include <QtGui/qtextformat.h>
|
||||||
#include <QtFontDatabaseSupport/private/qcoretextfontdatabase_p.h>
|
#include <QtFontDatabaseSupport/private/qcoretextfontdatabase_p.h>
|
||||||
#include <QtThemeSupport/private/qabstractfileiconengine_p.h>
|
#include <QtThemeSupport/private/qabstractfileiconengine_p.h>
|
||||||
#include <qpa/qplatformdialoghelper.h>
|
#include <qpa/qplatformdialoghelper.h>
|
||||||
@ -344,6 +345,8 @@ QVariant QCocoaTheme::themeHint(ThemeHint hint) const
|
|||||||
return QVariant(QChar(0x2022));
|
return QVariant(QChar(0x2022));
|
||||||
case QPlatformTheme::UiEffects:
|
case QPlatformTheme::UiEffects:
|
||||||
return QVariant(int(HoverEffect));
|
return QVariant(int(HoverEffect));
|
||||||
|
case QPlatformTheme::SpellCheckUnderlineStyle:
|
||||||
|
return QVariant(int(QTextCharFormat::DotLine));
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -262,7 +262,7 @@ public: // for QNSView
|
|||||||
|
|
||||||
bool m_hasModalSession;
|
bool m_hasModalSession;
|
||||||
bool m_frameStrutEventsEnabled;
|
bool m_frameStrutEventsEnabled;
|
||||||
bool m_isExposed;
|
QRect m_exposedRect;
|
||||||
int m_registerTouchCount;
|
int m_registerTouchCount;
|
||||||
bool m_resizableTransientParent;
|
bool m_resizableTransientParent;
|
||||||
|
|
||||||
|
@ -150,7 +150,6 @@ QCocoaWindow::QCocoaWindow(QWindow *win, WId nativeHandle)
|
|||||||
, m_needsInvalidateShadow(false)
|
, m_needsInvalidateShadow(false)
|
||||||
, m_hasModalSession(false)
|
, m_hasModalSession(false)
|
||||||
, m_frameStrutEventsEnabled(false)
|
, m_frameStrutEventsEnabled(false)
|
||||||
, m_isExposed(false)
|
|
||||||
, m_registerTouchCount(0)
|
, m_registerTouchCount(0)
|
||||||
, m_resizableTransientParent(false)
|
, m_resizableTransientParent(false)
|
||||||
, m_alertRequest(NoAlertRequest)
|
, m_alertRequest(NoAlertRequest)
|
||||||
@ -692,7 +691,7 @@ void QCocoaWindow::lower()
|
|||||||
|
|
||||||
bool QCocoaWindow::isExposed() const
|
bool QCocoaWindow::isExposed() const
|
||||||
{
|
{
|
||||||
return m_isExposed;
|
return !m_exposedRect.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QCocoaWindow::isOpaque() const
|
bool QCocoaWindow::isOpaque() const
|
||||||
@ -1120,7 +1119,7 @@ void QCocoaWindow::handleGeometryChange()
|
|||||||
|
|
||||||
void QCocoaWindow::handleExposeEvent(const QRegion ®ion)
|
void QCocoaWindow::handleExposeEvent(const QRegion ®ion)
|
||||||
{
|
{
|
||||||
const bool wasExposed = isExposed();
|
const QRect previouslyExposedRect = m_exposedRect;
|
||||||
|
|
||||||
// Ideally we'd implement isExposed() in terms of these properties,
|
// Ideally we'd implement isExposed() in terms of these properties,
|
||||||
// plus the occlusionState of the NSWindow, and let the expose event
|
// plus the occlusionState of the NSWindow, and let the expose event
|
||||||
@ -1133,27 +1132,29 @@ void QCocoaWindow::handleExposeEvent(const QRegion ®ion)
|
|||||||
// a window being obscured is an empty region, and in the case of
|
// a window being obscured is an empty region, and in the case of
|
||||||
// a drawRect call is a non-null region, even if occlusionState
|
// a drawRect call is a non-null region, even if occlusionState
|
||||||
// is still hidden. This ensures the window is prepared for display.
|
// is still hidden. This ensures the window is prepared for display.
|
||||||
m_isExposed = m_view.window.visible
|
if (m_view.window.visible && m_view.window.screen
|
||||||
&& m_view.window.screen
|
&& !geometry().size().isEmpty() && !region.isEmpty()
|
||||||
&& !geometry().size().isEmpty()
|
&& !m_view.hiddenOrHasHiddenAncestor) {
|
||||||
&& !region.isEmpty()
|
m_exposedRect = region.boundingRect();
|
||||||
&& !m_view.hiddenOrHasHiddenAncestor;
|
} else {
|
||||||
|
m_exposedRect = QRect();
|
||||||
|
}
|
||||||
|
|
||||||
QWindowPrivate *windowPrivate = qt_window_private(window());
|
QWindowPrivate *windowPrivate = qt_window_private(window());
|
||||||
if (windowPrivate->updateRequestPending) {
|
if (windowPrivate->updateRequestPending) {
|
||||||
// We can only deliver update request events when the window is exposed,
|
// We can only deliver update request events when the window is exposed,
|
||||||
// and we also have to make sure we deliver the first expose event after
|
// and we also have to make sure we deliver any change to the exposed
|
||||||
// becoming exposed as a real expose event, otherwise the exposed state
|
// rect as a real expose event (including going from non-exposed to
|
||||||
// of the QWindow is never updated.
|
// exposed). FIXME: Should this logic live in QGuiApplication?
|
||||||
// FIXME: Should this logic live in QGuiApplication?
|
if (isExposed() && m_exposedRect == previouslyExposedRect) {
|
||||||
if (wasExposed && m_isExposed) {
|
|
||||||
qCDebug(lcQpaCocoaWindow) << "QCocoaWindow::handleExposeEvent" << window() << region << "as update request";
|
qCDebug(lcQpaCocoaWindow) << "QCocoaWindow::handleExposeEvent" << window() << region << "as update request";
|
||||||
windowPrivate->deliverUpdateRequest();
|
windowPrivate->deliverUpdateRequest();
|
||||||
return;
|
return;
|
||||||
|
} else {
|
||||||
|
// Since updateRequestPending is still set, we will issue a deferred setNeedsDisplay
|
||||||
|
// from drawRect and get back into this code on the next display cycle, delivering
|
||||||
|
// the pending update request.
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Should we re-trigger setNeedsDisplay in case of !wasExposed && m_isExposed?
|
|
||||||
// Or possibly send the expose event first, and then the update request?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
qCDebug(lcQpaCocoaWindow) << "QCocoaWindow::handleExposeEvent" << window() << region << "isExposed" << isExposed();
|
qCDebug(lcQpaCocoaWindow) << "QCocoaWindow::handleExposeEvent" << window() << region << "isExposed" << isExposed();
|
||||||
@ -1669,6 +1670,7 @@ void QCocoaWindow::applyContentBorderThickness(NSWindow *window)
|
|||||||
if (!m_drawContentBorderGradient) {
|
if (!m_drawContentBorderGradient) {
|
||||||
window.styleMask = window.styleMask & ~NSTexturedBackgroundWindowMask;
|
window.styleMask = window.styleMask & ~NSTexturedBackgroundWindowMask;
|
||||||
[window.contentView.superview setNeedsDisplay:YES];
|
[window.contentView.superview setNeedsDisplay:YES];
|
||||||
|
window.titlebarAppearsTransparent = NO;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1693,6 +1695,7 @@ void QCocoaWindow::applyContentBorderThickness(NSWindow *window)
|
|||||||
int effectiveBottomContentBorderThickness = m_bottomContentBorderThickness;
|
int effectiveBottomContentBorderThickness = m_bottomContentBorderThickness;
|
||||||
|
|
||||||
[window setStyleMask:[window styleMask] | NSTexturedBackgroundWindowMask];
|
[window setStyleMask:[window styleMask] | NSTexturedBackgroundWindowMask];
|
||||||
|
window.titlebarAppearsTransparent = YES;
|
||||||
|
|
||||||
[window setContentBorderThickness:effectiveTopContentBorderThickness forEdge:NSMaxYEdge];
|
[window setContentBorderThickness:effectiveTopContentBorderThickness forEdge:NSMaxYEdge];
|
||||||
[window setAutorecalculatesContentBorderThickness:NO forEdge:NSMaxYEdge];
|
[window setAutorecalculatesContentBorderThickness:NO forEdge:NSMaxYEdge];
|
||||||
|
@ -324,12 +324,13 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
|
|||||||
|
|
||||||
m_platformWindow->handleExposeEvent(exposedRegion);
|
m_platformWindow->handleExposeEvent(exposedRegion);
|
||||||
|
|
||||||
// A call to QWindow::requestUpdate was issued during the expose event, but
|
|
||||||
// AppKit will reset the needsDisplay state of the view after completing the
|
|
||||||
// current display cycle, so we need to defer the request to redisplay.
|
|
||||||
// FIXME: Perhaps this should be a trigger to enable CADisplayLink?
|
|
||||||
if (qt_window_private(m_platformWindow->window())->updateRequestPending) {
|
if (qt_window_private(m_platformWindow->window())->updateRequestPending) {
|
||||||
qCDebug(lcQpaCocoaWindow) << "[QNSView drawRect:] deferring setNeedsDisplay";
|
// A call to QWindow::requestUpdate was issued during the expose event, or we
|
||||||
|
// had to deliver a real expose event and still need to deliver the update.
|
||||||
|
// But AppKit will reset the needsDisplay state of the view after completing
|
||||||
|
// the current display cycle, so we need to defer the request to redisplay.
|
||||||
|
// FIXME: Perhaps this should be a trigger to enable CADisplayLink?
|
||||||
|
qCDebug(lcQpaCocoaWindow) << "[QNSView drawRect:] issuing deferred setNeedsDisplay due to pending update request";
|
||||||
dispatch_async(dispatch_get_main_queue (), ^{
|
dispatch_async(dispatch_get_main_queue (), ^{
|
||||||
[self setNeedsDisplay:YES];
|
[self setNeedsDisplay:YES];
|
||||||
});
|
});
|
||||||
|
@ -2,9 +2,10 @@ TARGET = qdirect2d
|
|||||||
|
|
||||||
QT += \
|
QT += \
|
||||||
core-private gui-private \
|
core-private gui-private \
|
||||||
eventdispatcher_support-private accessibility_support-private \
|
eventdispatcher_support-private \
|
||||||
fontdatabase_support-private theme_support-private
|
fontdatabase_support-private theme_support-private
|
||||||
|
|
||||||
|
qtConfig(accessibility): QT += accessibility_support-private
|
||||||
qtConfig(vulkan): QT += vulkan_support-private
|
qtConfig(vulkan): QT += vulkan_support-private
|
||||||
|
|
||||||
LIBS += -ldwmapi -ld2d1 -ld3d11 -ldwrite -lVersion -lgdi32
|
LIBS += -ldwmapi -ld2d1 -ld3d11 -ldwrite -lVersion -lgdi32
|
||||||
|
@ -47,7 +47,9 @@
|
|||||||
#include "qwindowsmenu.h"
|
#include "qwindowsmenu.h"
|
||||||
#include "qwindowsmime.h"
|
#include "qwindowsmime.h"
|
||||||
#include "qwindowsinputcontext.h"
|
#include "qwindowsinputcontext.h"
|
||||||
|
#if QT_CONFIG(tabletevent)
|
||||||
# include "qwindowstabletsupport.h"
|
# include "qwindowstabletsupport.h"
|
||||||
|
#endif
|
||||||
#include "qwindowstheme.h"
|
#include "qwindowstheme.h"
|
||||||
#include <private/qguiapplication_p.h>
|
#include <private/qguiapplication_p.h>
|
||||||
#ifndef QT_NO_ACCESSIBILITY
|
#ifndef QT_NO_ACCESSIBILITY
|
||||||
|
@ -39,7 +39,9 @@
|
|||||||
|
|
||||||
#define QT_NO_URL_CAST_FROM_STRING 1
|
#define QT_NO_URL_CAST_FROM_STRING 1
|
||||||
|
|
||||||
#define _WIN32_WINNT 0x0600
|
#ifndef _WIN32_WINNT
|
||||||
|
#define _WIN32_WINNT 0x0601
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "qwindowscombase.h"
|
#include "qwindowscombase.h"
|
||||||
#include "qwindowsdialoghelpers.h"
|
#include "qwindowsdialoghelpers.h"
|
||||||
|
@ -37,13 +37,6 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#if defined(WINVER) && WINVER < 0x0601
|
|
||||||
# undef WINVER
|
|
||||||
#endif
|
|
||||||
#if !defined(WINVER)
|
|
||||||
# define WINVER 0x0601 // Enable touch functions for MinGW
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "qwindowsmousehandler.h"
|
#include "qwindowsmousehandler.h"
|
||||||
#include "qwindowskeymapper.h"
|
#include "qwindowskeymapper.h"
|
||||||
#include "qwindowscontext.h"
|
#include "qwindowscontext.h"
|
||||||
|
@ -352,16 +352,26 @@ bool QWindowsTabletSupport::translateTabletProximityEvent(WPARAM /* wParam */, L
|
|||||||
{
|
{
|
||||||
PACKET proximityBuffer[1]; // we are only interested in the first packet in this case
|
PACKET proximityBuffer[1]; // we are only interested in the first packet in this case
|
||||||
const int totalPacks = QWindowsTabletSupport::m_winTab32DLL.wTPacketsGet(m_context, 1, proximityBuffer);
|
const int totalPacks = QWindowsTabletSupport::m_winTab32DLL.wTPacketsGet(m_context, 1, proximityBuffer);
|
||||||
if (!totalPacks)
|
|
||||||
return false;
|
|
||||||
if (!LOWORD(lParam)) {
|
if (!LOWORD(lParam)) {
|
||||||
qCDebug(lcQpaTablet) << "leave proximity for device #" << m_currentDevice;
|
qCDebug(lcQpaTablet) << "leave proximity for device #" << m_currentDevice;
|
||||||
|
if (totalPacks > 0) {
|
||||||
QWindowSystemInterface::handleTabletLeaveProximityEvent(proximityBuffer[0].pkTime,
|
QWindowSystemInterface::handleTabletLeaveProximityEvent(proximityBuffer[0].pkTime,
|
||||||
m_devices.at(m_currentDevice).currentDevice,
|
m_devices.at(m_currentDevice).currentDevice,
|
||||||
m_devices.at(m_currentDevice).currentPointerType,
|
m_devices.at(m_currentDevice).currentPointerType,
|
||||||
m_devices.at(m_currentDevice).uniqueId);
|
m_devices.at(m_currentDevice).uniqueId);
|
||||||
|
} else {
|
||||||
|
QWindowSystemInterface::handleTabletLeaveProximityEvent(m_devices.at(m_currentDevice).currentDevice,
|
||||||
|
m_devices.at(m_currentDevice).currentPointerType,
|
||||||
|
m_devices.at(m_currentDevice).uniqueId);
|
||||||
|
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!totalPacks)
|
||||||
|
return false;
|
||||||
|
|
||||||
const UINT currentCursor = proximityBuffer[0].pkCursor;
|
const UINT currentCursor = proximityBuffer[0].pkCursor;
|
||||||
UINT physicalCursorId;
|
UINT physicalCursorId;
|
||||||
QWindowsTabletSupport::m_winTab32DLL.wTInfo(WTI_CURSORS + currentCursor, CSR_PHYSID, &physicalCursorId);
|
QWindowsTabletSupport::m_winTab32DLL.wTInfo(WTI_CURSORS + currentCursor, CSR_PHYSID, &physicalCursorId);
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user