summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2019-01-04 12:11:11 +0100
committerLiang Qi <liang.qi@qt.io>2019-01-04 13:03:26 +0100
commit7b23692538f55d499bf094a750311e1e4cd13ec6 (patch)
tree7e85cdabe0e069ee8fcbc3da3764327b4f8e2ba2
parentaa316d1d463777612db4b144d945bbaf67481494 (diff)
parent32897fd0b98966d22ecbd475a0e6a77ca8b1108d (diff)
downloadqttools-7b23692538f55d499bf094a750311e1e4cd13ec6.tar.gz
Merge remote-tracking branch 'origin/5.12' into dev
Conflicts: src/qdoc/htmlgenerator.cpp src/qtattributionsscanner/qdocgenerator.cpp Done-With: Martin Smith <martin.smith@qt.io> Change-Id: I56a23175579a1a699939179da2f35bbcd6c73367
-rw-r--r--dist/changes-5.11.332
-rw-r--r--dist/changes-5.12.060
-rw-r--r--qttools.pro2
-rw-r--r--src/assistant/assistant/doc/src/assistant-manual.qdoc2
-rw-r--r--src/assistant/assistant/main.cpp1
-rw-r--r--src/assistant/help/qhelpcollectionhandler.cpp8
-rw-r--r--src/designer/src/components/formeditor/images/win/filesave.pngbin1205 -> 2699 bytes
-rw-r--r--src/designer/src/components/propertyeditor/propertyeditor.cpp11
-rw-r--r--src/designer/src/components/taskmenu/itemlisteditor.cpp12
-rw-r--r--src/designer/src/components/taskmenu/itemlisteditor.h2
-rw-r--r--src/designer/src/components/taskmenu/tablewidgeteditor.cpp6
-rw-r--r--src/designer/src/components/taskmenu/tablewidgeteditor.h1
-rw-r--r--src/designer/src/components/taskmenu/treewidgeteditor.cpp6
-rw-r--r--src/designer/src/components/taskmenu/treewidgeteditor.h1
-rw-r--r--src/designer/src/designer/doc/src/designer-manual.qdoc94
-rw-r--r--src/designer/src/lib/uilib/uilib.pri2
-rw-r--r--src/distancefieldgenerator/main.cpp19
-rw-r--r--src/distancefieldgenerator/mainwindow.cpp100
-rw-r--r--src/distancefieldgenerator/mainwindow.h6
-rw-r--r--src/distancefieldgenerator/mainwindow.ui34
-rw-r--r--src/linguist/linguist/doc/snippets/doc_src_linguist-manual.pro5
-rw-r--r--src/linguist/linguist/doc/src/linguist-manual.qdoc21
-rw-r--r--src/linguist/linguist/images/mac/filesave.pngbin1206 -> 2699 bytes
-rw-r--r--src/linguist/linguist/images/win/filesave.pngbin1205 -> 2699 bytes
-rw-r--r--src/linguist/lupdate/cpp.cpp9
-rw-r--r--src/linguist/shared/translator.cpp9
-rw-r--r--src/linguist/shared/translatormessage.cpp6
-rw-r--r--src/qdoc/doc/qdoc-manual-markupcmds.qdoc3
-rw-r--r--src/qdoc/htmlgenerator.cpp90
-rw-r--r--src/qdoc/node.cpp5
-rw-r--r--src/qdoc/qdocdatabase.h3
-rw-r--r--src/qdoc/tree.cpp8
-rw-r--r--src/qtattributionsscanner/qdocgenerator.cpp2
-rw-r--r--src/shared/winutils/qmlutils.cpp4
-rw-r--r--src/shared/winutils/qmlutils.h3
-rw-r--r--src/shared/winutils/utils.cpp32
-rw-r--r--src/shared/winutils/utils.h17
-rw-r--r--src/windeployqt/main.cpp151
-rw-r--r--src/winrtrunner/appxlocalengine.cpp25
-rw-r--r--src/winrtrunner/appxlocalengine.h1
-rw-r--r--src/winrtrunner/appxphoneengine.cpp6
-rw-r--r--src/winrtrunner/appxphoneengine.h1
-rw-r--r--src/winrtrunner/main.cpp25
-rw-r--r--src/winrtrunner/runner.cpp8
-rw-r--r--src/winrtrunner/runner.h1
-rw-r--r--src/winrtrunner/runnerengine.h1
46 files changed, 572 insertions, 263 deletions
diff --git a/dist/changes-5.11.3 b/dist/changes-5.11.3
new file mode 100644
index 000000000..4e0a0b187
--- /dev/null
+++ b/dist/changes-5.11.3
@@ -0,0 +1,32 @@
+Qt 5.11.3 is a bug-fix release. It maintains both forward and backward
+compatibility (source and binary) with Qt 5.11.0 through 5.11.2.
+
+For more details, refer to the online documentation included in this
+distribution. The documentation is also available online:
+
+http://doc.qt.io/qt-5/index.html
+
+The Qt version 5.11 series is binary compatible with the 5.10.x series.
+Applications compiled for 5.10 will continue to run with 5.11.
+
+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.
+
+****************************************************************************
+* macdeployqt *
+****************************************************************************
+
+ - [QTBUG-68823] Now deploys plugins when Qt is configured with
+ -no-framework
+
+****************************************************************************
+* Assistant *
+****************************************************************************
+
+ - [QTBUG-71399] Fix a crash when removing multiple documentation files
+ inside preferences dialog
diff --git a/dist/changes-5.12.0 b/dist/changes-5.12.0
new file mode 100644
index 000000000..7cbcf1d62
--- /dev/null
+++ b/dist/changes-5.12.0
@@ -0,0 +1,60 @@
+Qt 5.12 introduces many new features and improvements as well as bugfixes
+over the 5.11.x series. For more details, refer to the online documentation
+included in this distribution. The documentation is also available online:
+
+https://doc.qt.io/qt-5/index.html
+
+The Qt version 5.12 series is binary compatible with the 5.11.x series.
+Applications compiled for 5.11 will continue to run with 5.12.
+
+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.
+
+****************************************************************************
+* macdeployqt *
+****************************************************************************
+
+ - [QTBUG-68823] Now deploys plugins when Qt is configured with
+ -no-framework
+
+****************************************************************************
+* winrtrunner *
+****************************************************************************
+
+ - Loopback exemption for UWP applications:
+ * Added ability to enable loopback exemption for clients. This basically
+ enables UWP applications to connect to a local server for debugging
+ purposes.
+ * Added ability to enable loopback exemption for servers. This basically
+ enables UWP applications to react on socket connections that are made
+ from the same machine for debugging purposes.
+
+****************************************************************************
+* Qt Help *
+****************************************************************************
+
+ - [QTCREATORBUG-18242] Fixed the issue with too many open files, when
+ many documentation files were registered.
+ - [QTBUG-59363] Fixed jumping to the proper documentation version
+ when activating the link that refers to another qch file.
+ - [QTBUG-21357] Items are now sorted alphabetically in Contents view.
+ - Removed qhelpconverter tool.
+ - Merged qcollectiongenerator tool into the qhelpgenerator tool.
+
+****************************************************************************
+* Qt Linguist *
+****************************************************************************
+
+ - Added "Go to" action to context menu in "Phrases and guesses" pane.
+
+lupdate
+-------
+
+ - [QTBUG-63364] Add support for C++17 nested namespaces.
+ - [QTBUG-62478] Fixed premature termination on qmake .prf execution errors.
+ - Updated qmake project handling to newer functionality in qmake.
diff --git a/qttools.pro b/qttools.pro
index b87dcea59..e7ae1f2b2 100644
--- a/qttools.pro
+++ b/qttools.pro
@@ -1,2 +1,2 @@
-load(qt_find_clang)
+!wasm:load(qt_find_clang)
load(qt_parts)
diff --git a/src/assistant/assistant/doc/src/assistant-manual.qdoc b/src/assistant/assistant/doc/src/assistant-manual.qdoc
index 9badfc260..c86a19cac 100644
--- a/src/assistant/assistant/doc/src/assistant-manual.qdoc
+++ b/src/assistant/assistant/doc/src/assistant-manual.qdoc
@@ -251,7 +251,7 @@
file in the \c{file} tags. It is possible to specify a different file or any
language. The icon defined by the \c{icon} tags is applied to any language.
\row
- \li \c{<cacheDirectory base="collection > default">}
+ \li \c{<cacheDirectory>, <cacheDirectory base="collection">}
\li Specifies the cache directory that is used to store index files
needed for the full text search and a copy of the collection file.
The copy is needed because \QA stores all its settings in the
diff --git a/src/assistant/assistant/main.cpp b/src/assistant/assistant/main.cpp
index 04f0fc968..ac20872bd 100644
--- a/src/assistant/assistant/main.cpp
+++ b/src/assistant/assistant/main.cpp
@@ -268,6 +268,7 @@ void setupTranslations()
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
+ QCoreApplication::setAttribute(Qt::AA_DisableWindowContextHelpButton);
TRACE_OBJ
QScopedPointer<QCoreApplication> a(createApplication(argc, argv));
#if QT_CONFIG(library)
diff --git a/src/assistant/help/qhelpcollectionhandler.cpp b/src/assistant/help/qhelpcollectionhandler.cpp
index 0cb6264dd..789e490ed 100644
--- a/src/assistant/help/qhelpcollectionhandler.cpp
+++ b/src/assistant/help/qhelpcollectionhandler.cpp
@@ -210,8 +210,10 @@ bool QHelpCollectionHandler::openCollectionFile()
const FileInfoList &docList = registeredDocumentations();
if (indexAndNamespaceFilterTablesMissing) {
for (const QHelpCollectionHandler::FileInfo &info : docList) {
- if (!registerIndexAndNamespaceFilterTables(info.namespaceName))
+ if (!registerIndexAndNamespaceFilterTables(info.namespaceName)) {
+ emit error(tr("Cannot register index tables in file %1.").arg(collectionFile()));
return false;
+ }
}
return true;
}
@@ -239,8 +241,10 @@ bool QHelpCollectionHandler::openCollectionFile()
// In this case we remove all records from tables.
Transaction transaction(m_connectionName);
for (const TimeStamp &timeStamp : toRemove) {
- if (!unregisterIndexTable(timeStamp.namespaceId, timeStamp.folderId))
+ if (!unregisterIndexTable(timeStamp.namespaceId, timeStamp.folderId)) {
+ emit error(tr("Cannot unregister index tables in file %1.").arg(collectionFile()));
return false;
+ }
}
transaction.commit();
diff --git a/src/designer/src/components/formeditor/images/win/filesave.png b/src/designer/src/components/formeditor/images/win/filesave.png
index 8feec99be..e65a29d5f 100644
--- a/src/designer/src/components/formeditor/images/win/filesave.png
+++ b/src/designer/src/components/formeditor/images/win/filesave.png
Binary files differ
diff --git a/src/designer/src/components/propertyeditor/propertyeditor.cpp b/src/designer/src/components/propertyeditor/propertyeditor.cpp
index 1fee704d2..d393caee5 100644
--- a/src/designer/src/components/propertyeditor/propertyeditor.cpp
+++ b/src/designer/src/components/propertyeditor/propertyeditor.cpp
@@ -913,8 +913,15 @@ void PropertyEditor::setObject(QObject *object)
m_object = object;
m_propertyManager->setObject(object);
QDesignerFormWindowInterface *formWindow = QDesignerFormWindowInterface::findFormWindow(m_object);
- if (Q_UNLIKELY(formWindow == nullptr)) // QTBUG-68507, can happen in Morph Undo macros with buddies
- return;
+ // QTBUG-68507: Form window can be null for objects in Morph Undo macros with buddies
+ if (object != nullptr && formWindow == nullptr) {
+ formWindow = m_core->formWindowManager()->activeFormWindow();
+ if (formWindow == nullptr) {
+ qWarning("PropertyEditor::setObject(): Unable to find form window for \"%s\".",
+ qPrintable(object->objectName()));
+ return;
+ }
+ }
FormWindowBase *fwb = qobject_cast<FormWindowBase *>(formWindow);
const bool idIdBasedTranslation = fwb && fwb->useIdBasedTranslations();
const bool idIdBasedTranslationUnchanged = (idIdBasedTranslation == DesignerPropertyManager::useIdBasedTranslations());
diff --git a/src/designer/src/components/taskmenu/itemlisteditor.cpp b/src/designer/src/components/taskmenu/itemlisteditor.cpp
index d0a1a8308..a5ec15e48 100644
--- a/src/designer/src/components/taskmenu/itemlisteditor.cpp
+++ b/src/designer/src/components/taskmenu/itemlisteditor.cpp
@@ -168,7 +168,7 @@ void AbstractItemEditor::propertyChanged(QtProperty *property)
// Subproperty
return;
- if ((role == ItemFlagsShadowRole && prop->value().toInt() == int(QListWidgetItem().flags()))
+ if ((role == ItemFlagsShadowRole && prop->value().toInt() == defaultItemFlags())
|| (role == Qt::DecorationPropertyRole && !qvariant_cast<PropertySheetIconValue>(prop->value()).mask())
|| (role == Qt::FontRole && !qvariant_cast<QFont>(prop->value()).resolve())) {
prop->setModified(false);
@@ -214,7 +214,7 @@ void AbstractItemEditor::resetProperty(QtProperty *property)
QtVariantProperty *prop = m_propertyManager->variantProperty(property);
int role = m_propertyToRole.value(prop);
if (role == ItemFlagsShadowRole)
- prop->setValue(QVariant::fromValue(int(QListWidgetItem().flags())));
+ prop->setValue(QVariant::fromValue(defaultItemFlags()));
else
prop->setValue(QVariant(prop->valueType(), nullptr));
prop->setModified(false);
@@ -246,7 +246,7 @@ void AbstractItemEditor::updateBrowser()
QVariant val = getItemData(role);
if (!val.isValid()) {
if (role == ItemFlagsShadowRole)
- val = QVariant::fromValue(int(QListWidgetItem().flags()));
+ val = QVariant::fromValue(defaultItemFlags());
else
val = QVariant(int(prop->value().userType()), nullptr);
prop->setModified(false);
@@ -430,6 +430,12 @@ QVariant ItemListEditor::getItemData(int role) const
return ui.listWidget->currentItem()->data(role);
}
+int ItemListEditor::defaultItemFlags() const
+{
+ static const int flags = QListWidgetItem().flags();
+ return flags;
+}
+
void ItemListEditor::cacheReloaded()
{
reloadIconResources(iconCache(), ui.listWidget);
diff --git a/src/designer/src/components/taskmenu/itemlisteditor.h b/src/designer/src/components/taskmenu/itemlisteditor.h
index ea0634eed..e9b292446 100644
--- a/src/designer/src/components/taskmenu/itemlisteditor.h
+++ b/src/designer/src/components/taskmenu/itemlisteditor.h
@@ -85,6 +85,7 @@ private slots:
void resetProperty(QtProperty *property);
protected:
+ virtual int defaultItemFlags() const = 0;
void setupProperties(PropertyDefinition *propDefs);
void setupObject(QWidget *object);
void setupEditor(QWidget *object, PropertyDefinition *propDefs);
@@ -138,6 +139,7 @@ private slots:
protected:
void setItemData(int role, const QVariant &v) override;
QVariant getItemData(int role) const override;
+ int defaultItemFlags() const override;
private:
void setPropertyBrowserVisible(bool v);
diff --git a/src/designer/src/components/taskmenu/tablewidgeteditor.cpp b/src/designer/src/components/taskmenu/tablewidgeteditor.cpp
index 4a28a2f44..b1a7adf12 100644
--- a/src/designer/src/components/taskmenu/tablewidgeteditor.cpp
+++ b/src/designer/src/components/taskmenu/tablewidgeteditor.cpp
@@ -184,6 +184,12 @@ QVariant TableWidgetEditor::getItemData(int role) const
return item->data(role);
}
+int TableWidgetEditor::defaultItemFlags() const
+{
+ static const int flags = QTableWidgetItem().flags();
+ return flags;
+}
+
void TableWidgetEditor::on_tableWidget_currentCellChanged(int currentRow, int currentCol, int, int /* XXX remove me */)
{
m_rowEditor->setCurrentIndex(currentRow);
diff --git a/src/designer/src/components/taskmenu/tablewidgeteditor.h b/src/designer/src/components/taskmenu/tablewidgeteditor.h
index 26ad05b49..72dbb58da 100644
--- a/src/designer/src/components/taskmenu/tablewidgeteditor.h
+++ b/src/designer/src/components/taskmenu/tablewidgeteditor.h
@@ -82,6 +82,7 @@ private slots:
protected:
void setItemData(int role, const QVariant &v) override;
QVariant getItemData(int role) const override;
+ int defaultItemFlags() const override;
private:
void setPropertyBrowserVisible(bool v);
diff --git a/src/designer/src/components/taskmenu/treewidgeteditor.cpp b/src/designer/src/components/taskmenu/treewidgeteditor.cpp
index 2ec0109a4..20c7bd0a5 100644
--- a/src/designer/src/components/taskmenu/treewidgeteditor.cpp
+++ b/src/designer/src/components/taskmenu/treewidgeteditor.cpp
@@ -196,6 +196,12 @@ QVariant TreeWidgetEditor::getItemData(int role) const
return ui.treeWidget->currentItem()->data(col, role);
}
+int TreeWidgetEditor::defaultItemFlags() const
+{
+ static const int flags = QTreeWidgetItem().flags();
+ return flags;
+}
+
void TreeWidgetEditor::on_newItemButton_clicked()
{
QTreeWidgetItem *curItem = ui.treeWidget->currentItem();
diff --git a/src/designer/src/components/taskmenu/treewidgeteditor.h b/src/designer/src/components/taskmenu/treewidgeteditor.h
index a0187678d..9b1a607e4 100644
--- a/src/designer/src/components/taskmenu/treewidgeteditor.h
+++ b/src/designer/src/components/taskmenu/treewidgeteditor.h
@@ -80,6 +80,7 @@ private slots:
protected:
void setItemData(int role, const QVariant &v) override;
QVariant getItemData(int role) const override;
+ int defaultItemFlags() const override;
private:
void setPropertyBrowserVisible(bool v);
diff --git a/src/designer/src/designer/doc/src/designer-manual.qdoc b/src/designer/src/designer/doc/src/designer-manual.qdoc
index dd060af3a..99f45ecdd 100644
--- a/src/designer/src/designer/doc/src/designer-manual.qdoc
+++ b/src/designer/src/designer/doc/src/designer-manual.qdoc
@@ -58,6 +58,7 @@
\section1 Table of Contents
\list
+ \li \l{A Quick Start to Qt Designer}
\li \l{Qt Designer's Editing Modes}
\list
\li \l{Qt Designer's Widget Editing Mode}{Widget Editing Mode}
@@ -507,7 +508,7 @@
each corner and the midpoint of each side, indicating that it can be
resized.
- To select additional objects, hold down the \key Shift key and click on
+ To select additional objects, hold down the \key Control key and click on
them. If more than one object is selected, the current object will be
displayed with resize handles of a different color.
@@ -696,43 +697,24 @@
form is previewed or used in an application. Placing objects in a layout
also ensures that they will be resized correctly when the form is resized.
-
- \tableofcontents
-
- \section1 Applying and Breaking Layouts
-
- The simplest way to manage objects is to apply a layout to a group of
- existing objects. This is achieved by selecting the objects that you need
- to manage and applying one of the standard layouts using the main toolbar,
- the \gui Form menu, or the form's context menu.
-
Once widgets have been inserted into a layout, it is not possible to move
and resize them individually because the layout itself controls the
geometry of each widget within it, taking account of the hints provided by
- spacers. Instead, you must either break the layout and adjust each object's
- geometry manually, or you can influence the widget's geometry by resizing
- the layout.
-
- To break the layout, press \key{Ctrl+0} or choose \gui{Break Layout} from
- the form's context menu, the \gui Form menu or the main toolbar. You can
- also add and remove spacers from the layout to influence the geometries of
+ spacers. Spacers can be added to the layout to influence the geometries of
the widgets.
+ Layouts can be nested to form a hierarchy. For example, to achieve a
+ typical dialog layout with a horizontal row of buttons, the dialog
+ elements can be laid out using a vertical box layout with a horizontal
+ box layout containing the buttons at the bottom. For an introduction to
+ the Qt layout system, refer to \l{Layout Management}.
- \target InsertingObjectsIntoALayout
- \table
- \row
- \li \inlineimage designer-layout-inserting.png
- \li \b{Inserting Objects into a Layout}
-
- Objects can be inserted into an existing layout by dragging them from
- their current positions and dropping them at the required location. A
- blue cursor is displayed in the layout as an object is dragged over
- it to indicate where the object will be added.
- \endtable
+ To break a layout, press \key{Ctrl+0} or choose \gui{Break Layout} from
+ the form's context menu, the \gui Form menu or the main toolbar.
+ \tableofcontents
- \section2 Setting A Top Level Layout
+ \section1 Setting A Top Level Layout
The form's top level layout can be set by clearing the selection (click the
left mouse button on the form itself) and applying a layout. A top level
@@ -749,10 +731,52 @@
toolbar shown on the left, or from the context menu shown below.
\endtable
+ Similary, top level layouts are set on container widgets (QGroupBox)
+ or on pages of page-based container widgets (QTabWidget, QToolBox
+ and QStackedWidget), respectively. The container widget needs to be
+ selected for this to succeed.
+
+ Top level layouts are not visible as separate objects in the Object
+ Inspector. Their properties appear below the widget properties of the
+ main form, container widget, or page of a container widget in the
+ Property Editor.
+
\image designer-set-layout2.png
- \section2 Horizontal and Vertical Layouts
+ \section1 Layout Objects
+
+ Layout objects are created by applying a layout to a group of
+ existing objects. This is achieved by selecting the objects that you need
+ to manage and applying one of the standard layouts using the main toolbar,
+ the \gui Form menu, or the form's context menu.
+
+ The layout object is indicated by a red frame on the form and appears as
+ an object in the Object Inspector. Its properties (margins and constraints)
+ are shown in the Property Editor.
+
+ The layout object can be selected and placed within another layout along
+ with other widgets and layout objects to build a layout hierarchy.
+
+ When a child layout object is selected, its parent layout object can be
+ selected by pressing down the \key Shift key while clicking on it. This
+ makes it possible to select a specific layout in a hierarchy, which is
+ otherwise difficult due to the small frame.
+
+
+ \section1 Inserting Objects Into a Layout
+ \target InsertingObjectsIntoALayout
+
+ Objects can be inserted into an existing layout by dragging them from
+ their current positions and dropping them at the required location. A
+ blue cursor is displayed in the layout as an object is dragged over
+ it to indicate where the object will be added.
+
+ \image designer-layout-inserting.png
+ \caption Inserting Objects into a Layout
+
+ \section1 Layout Types
+ \section2 Horizontal and Vertical (Box) Layouts
The simplest way to arrange objects on a form is to place them in a
horizontal or vertical layout. Horizontal layouts ensure that the widgets
@@ -764,7 +788,7 @@
using the grid layout.
- \section3 The Grid Layout
+ \section2 The Grid Layout
Complex form layouts can be created by placing objects in a grid layout.
This kind of layout gives the form designer much more freedom to arrange
@@ -773,7 +797,7 @@
suitable than a nested arrangement of horizontal and vertical layouts.
- \section3 The Form Layout
+ \section2 The Form Layout
The QFormLayout
class manages widgets in a two-column form; the left column holds labels
@@ -797,7 +821,7 @@
\endtable
-\section3 Splitter Layouts
+ \section2 Splitter Layouts
Another common way to manage the layout of objects on a form is to place
them in a splitter. These splitters arrange the objects horizontally or
@@ -814,7 +838,7 @@
keyboard shortcut, or \gui{Lay out} context menu entry.
- \section2 Shortcut Keys
+ \section1 Shortcut Keys
In addition to the standard toolbar and context menu entries, there is also
a set of keyboard shortcuts to apply layouts on widgets.
diff --git a/src/designer/src/lib/uilib/uilib.pri b/src/designer/src/lib/uilib/uilib.pri
index b757f4ee9..386414b67 100644
--- a/src/designer/src/lib/uilib/uilib.pri
+++ b/src/designer/src/lib/uilib/uilib.pri
@@ -24,3 +24,5 @@ SOURCES += \
$$PWD/formbuilderextra.cpp \
$$PWD/resourcebuilder.cpp \
$$PWD/textbuilder.cpp
+
+OTHER_FILES += $$PWD/widgets.table
diff --git a/src/distancefieldgenerator/main.cpp b/src/distancefieldgenerator/main.cpp
index c7b5cab13..53ada87ac 100644
--- a/src/distancefieldgenerator/main.cpp
+++ b/src/distancefieldgenerator/main.cpp
@@ -30,9 +30,6 @@
#include <QApplication>
#include <QCommandLineParser>
-#include <QFile>
-#include <QFileInfo>
-#include <QRawFont>
QT_USE_NAMESPACE
@@ -44,9 +41,21 @@ int main(int argc, char **argv)
app.setApplicationName(QStringLiteral("Qt Distance Field Generator"));
app.setApplicationVersion(QStringLiteral(QT_VERSION_STR));
+ QCommandLineParser parser;
+ parser.setApplicationDescription(
+ QCoreApplication::translate("main",
+ "Allows to prepare a font cache for Qt applications."));
+ parser.addHelpOption();
+ parser.addVersionOption();
+ parser.addPositionalArgument(QLatin1String("file"),
+ QCoreApplication::translate("main",
+ "Font file (*.ttf, *.otf)"));
+ parser.process(app);
+
MainWindow mainWindow;
- mainWindow.showMaximized();
+ if (!parser.positionalArguments().isEmpty())
+ mainWindow.open(parser.positionalArguments().constFirst());
+ mainWindow.show();
return app.exec();
}
-
diff --git a/src/distancefieldgenerator/mainwindow.cpp b/src/distancefieldgenerator/mainwindow.cpp
index 7108e387c..eef116ded 100644
--- a/src/distancefieldgenerator/mainwindow.cpp
+++ b/src/distancefieldgenerator/mainwindow.cpp
@@ -35,6 +35,7 @@
#include <QtCore/qmath.h>
#include <QtCore/qendian.h>
#include <QtCore/qbuffer.h>
+#include <QtGui/qdesktopservices.h>
#include <QtGui/qrawfont.h>
#include <QtWidgets/qmessagebox.h>
#include <QtWidgets/qlabel.h>
@@ -49,15 +50,23 @@
QT_BEGIN_NAMESPACE
+static void openHelp()
+{
+ QDesktopServices::openUrl(QUrl(QLatin1String("http://doc.qt.io/qt-5/qtdistancefieldgenerator-index.html")));
+}
+
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
, m_settings(qApp->organizationName(), qApp->applicationName())
- , m_model(nullptr)
+ , m_model(new DistanceFieldModel(this))
, m_statusBarLabel(nullptr)
, m_statusBarProgressBar(nullptr)
{
ui->setupUi(this);
+ ui->lvGlyphs->setModel(m_model);
+
+ ui->actionHelp->setShortcut(QKeySequence::HelpContents);
m_statusBarLabel = new QLabel(this);
m_statusBarLabel->setText(tr("Ready"));
@@ -75,6 +84,8 @@ MainWindow::MainWindow(QWidget *parent)
qRegisterMetaType<glyph_t>("glyph_t");
qRegisterMetaType<QPainterPath>("QPainterPath");
+ restoreGeometry(m_settings.value(QStringLiteral("geometry")).toByteArray());
+
setupConnections();
}
@@ -83,6 +94,27 @@ MainWindow::~MainWindow()
delete ui;
}
+void MainWindow::open(const QString &path)
+{
+ m_fileName.clear();
+ m_fontFile = path;
+ m_fontDir = QFileInfo(path).absolutePath();
+ m_settings.setValue(QStringLiteral("fontDirectory"), m_fontDir);
+
+ ui->lwUnicodeRanges->clear();
+ ui->lwUnicodeRanges->setDisabled(true);
+ ui->action_Save->setDisabled(true);
+ ui->action_Save_as->setDisabled(true);
+ ui->tbSave->setDisabled(true);
+ ui->action_Open->setDisabled(true);
+ m_model->setFont(path);
+}
+
+void MainWindow::closeEvent(QCloseEvent * /*event*/)
+{
+ m_settings.setValue(QStringLiteral("geometry"), saveGeometry());
+}
+
void MainWindow::setupConnections()
{
connect(ui->action_Open, &QAction::triggered, this, &MainWindow::openFont);
@@ -93,7 +125,22 @@ void MainWindow::setupConnections()
connect(ui->tbSelectAll, &QToolButton::clicked, this, &MainWindow::selectAll);
connect(ui->actionSelect_all, &QAction::triggered, this, &MainWindow::selectAll);
connect(ui->actionSelect_string, &QAction::triggered, this, &MainWindow::selectString);
+ connect(ui->actionHelp, &QAction::triggered, this, openHelp);
+ connect(ui->actionAbout_App, &QAction::triggered, this, &MainWindow::about);
+ connect(ui->actionAbout_Qt, &QAction::triggered, this, [this]() {
+ QMessageBox::aboutQt(this);
+ });
connect(ui->lwUnicodeRanges, &QListWidget::itemSelectionChanged, this, &MainWindow::updateUnicodeRanges);
+
+ connect(ui->lvGlyphs->selectionModel(),
+ &QItemSelectionModel::selectionChanged,
+ this,
+ &MainWindow::updateSelection);
+ connect(m_model, &DistanceFieldModel::startGeneration, this, &MainWindow::startProgressBar);
+ connect(m_model, &DistanceFieldModel::stopGeneration, this, &MainWindow::stopProgressBar);
+ connect(m_model, &DistanceFieldModel::distanceFieldGenerated, this, &MainWindow::updateProgressBar);
+ connect(m_model, &DistanceFieldModel::stopGeneration, this, &MainWindow::populateUnicodeRanges);
+ connect(m_model, &DistanceFieldModel::error, this, &MainWindow::displayError);
}
void MainWindow::saveAs()
@@ -552,36 +599,8 @@ void MainWindow::openFont()
tr("Open font file"),
m_fontDir,
tr("Fonts (*.ttf *.otf);;All files (*)"));
- if (!fileName.isEmpty()) {
- m_fileName.clear();
- m_fontFile = fileName;
- m_fontDir = QFileInfo(fileName).absolutePath();
- m_settings.setValue(QStringLiteral("fontDirectory"), m_fontDir);
-
- if (m_model == nullptr) {
- m_model = new DistanceFieldModel(this);
- connect(m_model, &DistanceFieldModel::startGeneration, this, &MainWindow::startProgressBar);
- connect(m_model, &DistanceFieldModel::stopGeneration, this, &MainWindow::stopProgressBar);
- connect(m_model, &DistanceFieldModel::distanceFieldGenerated, this, &MainWindow::updateProgressBar);
- connect(m_model, &DistanceFieldModel::stopGeneration, this, &MainWindow::populateUnicodeRanges);
- connect(m_model, &DistanceFieldModel::error, this, &MainWindow::displayError);
-
- ui->lvGlyphs->setModel(m_model);
-
- connect(ui->lvGlyphs->selectionModel(),
- &QItemSelectionModel::selectionChanged,
- this,
- &MainWindow::updateSelection);
- }
-
- ui->lwUnicodeRanges->clear();
- ui->lwUnicodeRanges->setDisabled(true);
- ui->action_Save->setDisabled(true);
- ui->action_Save_as->setDisabled(true);
- ui->tbSave->setDisabled(true);
- ui->action_Open->setDisabled(true);
- m_model->setFont(fileName);
- }
+ if (!fileName.isEmpty())
+ open(fileName);
}
void MainWindow::updateProgressBar()
@@ -620,9 +639,9 @@ void MainWindow::updateSelection()
QModelIndexList list = ui->lvGlyphs->selectionModel()->selectedIndexes();
QString label;
if (list.size() == ui->lvGlyphs->model()->rowCount())
- label = tr("Deselect &all");
+ label = tr("Deselect &All");
else
- label = tr("Select &all");
+ label = tr("Select &All");
ui->tbSelectAll->setText(label);
ui->actionSelect_all->setText(label);
@@ -726,4 +745,19 @@ void MainWindow::selectString()
}
}
+void MainWindow::about()
+{
+ QMessageBox *msgBox = new QMessageBox(this);
+ msgBox->setAttribute(Qt::WA_DeleteOnClose);
+ msgBox->setWindowTitle(tr("About Qt Distance Field Generator"));
+ msgBox->setText(tr("<h3>Qt Distance Field Generator</h3>"
+ "<p>Version %1.<br/>"
+ "The Qt Distance Field Generator tool allows "
+ "to prepare a font cache for Qt applications.</p>"
+ "<p>Copyright (C) %2 The Qt Company Ltd.</p>")
+ .arg(QLatin1String(QT_VERSION_STR))
+ .arg(QLatin1String("2018")));
+ msgBox->show();
+}
+
QT_END_NAMESPACE
diff --git a/src/distancefieldgenerator/mainwindow.h b/src/distancefieldgenerator/mainwindow.h
index dc209d558..89a83db52 100644
--- a/src/distancefieldgenerator/mainwindow.h
+++ b/src/distancefieldgenerator/mainwindow.h
@@ -49,6 +49,11 @@ public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
+ void open(const QString &path);
+
+protected:
+ void closeEvent(QCloseEvent *event) override;
+
private slots:
void openFont();
void startProgressBar(quint16 glyphCount);
@@ -62,6 +67,7 @@ private slots:
void saveAs();
void displayError(const QString &errorString);
void selectString();
+ void about();
private:
void setupConnections();
diff --git a/src/distancefieldgenerator/mainwindow.ui b/src/distancefieldgenerator/mainwindow.ui
index d1f58e537..e7fe0d788 100644
--- a/src/distancefieldgenerator/mainwindow.ui
+++ b/src/distancefieldgenerator/mainwindow.ui
@@ -121,7 +121,7 @@
<x>0</x>
<y>0</y>
<width>800</width>
- <height>19</height>
+ <height>23</height>
</rect>
</property>
<widget class="QMenu" name="menu_File">
@@ -141,13 +141,22 @@
<addaction name="actionSelect_all"/>
<addaction name="actionSelect_string"/>
</widget>
+ <widget class="QMenu" name="menu_Help">
+ <property name="title">
+ <string>&amp;Help</string>
+ </property>
+ <addaction name="actionHelp"/>
+ <addaction name="actionAbout_App"/>
+ <addaction name="actionAbout_Qt"/>
+ </widget>
<addaction name="menu_File"/>
<addaction name="menu_Select"/>
+ <addaction name="menu_Help"/>
</widget>
<widget class="QStatusBar" name="statusbar"/>
<action name="action_Open">
<property name="text">
- <string>&amp;Open font</string>
+ <string>&amp;Open Font...</string>
</property>
<property name="shortcut">
<string>Ctrl+O</string>
@@ -155,7 +164,7 @@
</action>
<action name="action_Save_as">
<property name="text">
- <string>Save &amp;as...</string>
+ <string>Save &amp;As...</string>
</property>
</action>
<action name="action_Save">
@@ -176,7 +185,7 @@
</action>
<action name="actionSelect_all">
<property name="text">
- <string>Select &amp;all</string>
+ <string>Select &amp;All</string>
</property>
<property name="shortcut">
<string>Ctrl+A</string>
@@ -184,7 +193,22 @@
</action>
<action name="actionSelect_string">
<property name="text">
- <string>Select &amp;string</string>
+ <string>Select &amp;String</string>
+ </property>
+ </action>
+ <action name="actionAbout_App">
+ <property name="text">
+ <string>About Qt Distance Field Generator</string>
+ </property>
+ </action>
+ <action name="actionAbout_Qt">
+ <property name="text">
+ <string>About Qt</string>
+ </property>
+ </action>
+ <action name="actionHelp">
+ <property name="text">
+ <string>Help</string>
</property>
</action>
</widget>
diff --git a/src/linguist/linguist/doc/snippets/doc_src_linguist-manual.pro b/src/linguist/linguist/doc/snippets/doc_src_linguist-manual.pro
index 511bd942b..ccb27f421 100644
--- a/src/linguist/linguist/doc/snippets/doc_src_linguist-manual.pro
+++ b/src/linguist/linguist/doc/snippets/doc_src_linguist-manual.pro
@@ -60,8 +60,3 @@ TRANSLATIONS = superapp_dk.ts \
superapp_no.ts \
superapp_se.ts
#! [0]
-
-
-#! [2]
-CODECFORSRC = UTF-8
-#! [2]
diff --git a/src/linguist/linguist/doc/src/linguist-manual.qdoc b/src/linguist/linguist/doc/src/linguist-manual.qdoc
index c93515e9d..403e4652c 100644
--- a/src/linguist/linguist/doc/src/linguist-manual.qdoc
+++ b/src/linguist/linguist/doc/src/linguist-manual.qdoc
@@ -869,18 +869,15 @@
\snippet doc_src_linguist-manual.pro 0
- If your compiler uses a different encoding for its runtime
- system than for its source code and you want to use non-ASCII
- characters in string literals, you will need to set the \c
- CODECFORSRC. For example:
-
- \snippet doc_src_linguist-manual.pro 2
-
- Microsoft Visual Studio 2005 .NET appears to be the only compiler
- for which this is necessary. However, if you want to write
- portable code, we recommend that you avoid non-ASCII characters
- in your source files. You can still specify non-ASCII characters
- portably using escape sequences, for example:
+ \c lupdate expects all source code to be encoded in UTF-8 by default.
+ Files that feature a BOM (Byte Order Mark) can also be encoded in
+ UTF-16 or UTF-32. Set the qmake variable \c CODECFORSRC to
+ \c UTF-16 to parse files without a BOM as UTF-16.
+
+ Some editors, such as Visual Studio, however use a different
+ encoding by default. One way to avoid encoding issues is to limit any
+ source code to ASCII, and use escape sequences for translatable strings
+ with other characters, for example:
\snippet doc_src_linguist-manual.cpp 3
diff --git a/src/linguist/linguist/images/mac/filesave.png b/src/linguist/linguist/images/mac/filesave.png
index b41ecf531..e65a29d5f 100644
--- a/src/linguist/linguist/images/mac/filesave.png
+++ b/src/linguist/linguist/images/mac/filesave.png
Binary files differ
diff --git a/src/linguist/linguist/images/win/filesave.png b/src/linguist/linguist/images/win/filesave.png
index 8feec99be..e65a29d5f 100644
--- a/src/linguist/linguist/images/win/filesave.png
+++ b/src/linguist/linguist/images/win/filesave.png
Binary files differ
diff --git a/src/linguist/lupdate/cpp.cpp b/src/linguist/lupdate/cpp.cpp
index cd02de34f..3836bfcfd 100644
--- a/src/linguist/lupdate/cpp.cpp
+++ b/src/linguist/lupdate/cpp.cpp
@@ -2325,11 +2325,14 @@ void loadCPP(Translator &translator, const QStringList &filenames, ConversionDat
parser.recordResults(isHeader(filename));
}
- foreach (const QString &filename, filenames)
- if (!CppFiles::isBlacklisted(filename))
- if (const Translator *tor = CppFiles::getTranslator(filename))
+ foreach (const QString &filename, filenames) {
+ if (!CppFiles::isBlacklisted(filename)) {
+ if (const Translator *tor = CppFiles::getTranslator(filename)) {
foreach (const TranslatorMessage &msg, tor->messages())
translator.extend(msg, cd);
+ }
+ }
+ }
}
QT_END_NAMESPACE
diff --git a/src/linguist/shared/translator.cpp b/src/linguist/shared/translator.cpp
index 5b0538d4e..af669e235 100644
--- a/src/linguist/shared/translator.cpp
+++ b/src/linguist/shared/translator.cpp
@@ -384,11 +384,14 @@ int Translator::find(const QString &context,
{
if (!refs.isEmpty()) {
for (TMM::ConstIterator it = m_messages.constBegin(); it != m_messages.constEnd(); ++it) {
- if (it->context() == context && it->comment() == comment)
- foreach (const TranslatorMessage::Reference &itref, it->allReferences())
- foreach (const TranslatorMessage::Reference &ref, refs)
+ if (it->context() == context && it->comment() == comment) {
+ foreach (const TranslatorMessage::Reference &itref, it->allReferences()) {
+ foreach (const TranslatorMessage::Reference &ref, refs) {
if (itref == ref)
return it - m_messages.constBegin();
+ }
+ }
+ }
}
}
return -1;
diff --git a/src/linguist/shared/translatormessage.cpp b/src/linguist/shared/translatormessage.cpp
index f9048de70..0cc17f1de 100644
--- a/src/linguist/shared/translatormessage.cpp
+++ b/src/linguist/shared/translatormessage.cpp
@@ -73,10 +73,12 @@ void TranslatorMessage::addReferenceUniq(const QString &fileName, int lineNumber
} else {
if (fileName == m_fileName && lineNumber == m_lineNumber)
return;
- if (!m_extraRefs.isEmpty()) // Rather common case, so special-case it
- foreach (const Reference &ref, m_extraRefs)
+ if (!m_extraRefs.isEmpty()) { // Rather common case, so special-case it
+ foreach (const Reference &ref, m_extraRefs) {
if (fileName == ref.fileName() && lineNumber == ref.lineNumber())
return;
+ }
+ }
m_extraRefs.append(Reference(fileName, lineNumber));
}
}
diff --git a/src/qdoc/doc/qdoc-manual-markupcmds.qdoc b/src/qdoc/doc/qdoc-manual-markupcmds.qdoc
index 8ba6efa05..1b6648f90 100644
--- a/src/qdoc/doc/qdoc-manual-markupcmds.qdoc
+++ b/src/qdoc/doc/qdoc-manual-markupcmds.qdoc
@@ -1470,6 +1470,9 @@
{positioning} and \l {substring} {argument} as the \l
{printline-command} {\\printline} command.
+ If \\printuntil is used without an argument, it expands to all the
+ lines from the current position to the end of the quoted file.
+
The lines from the source file are rendered in a separate
paragraph, using a monospace font and the standard
indentation. The code is shown verbatim.
diff --git a/src/qdoc/htmlgenerator.cpp b/src/qdoc/htmlgenerator.cpp
index d7f9ae676..032490639 100644
--- a/src/qdoc/htmlgenerator.cpp
+++ b/src/qdoc/htmlgenerator.cpp
@@ -1431,7 +1431,6 @@ void HtmlGenerator::generateCppReferencePage(Node* node, CodeMarker* marker)
}
else {
if (!s->members().isEmpty()) {
- // out() << "<hr />\n";
QString ref = registerRef(s->title().toLower());
out() << "<a name=\"" << ref << "\"></a>" << divNavTop << "\n";
out() << "<h2 id=\"" << ref << "\">" << protectEnc(s->title()) << "</h2>\n";
@@ -1440,7 +1439,6 @@ void HtmlGenerator::generateCppReferencePage(Node* node, CodeMarker* marker)
if (!s->reimplementedMembers().isEmpty()) {
QString name = QString("Reimplemented ") + s->title();
QString ref = registerRef(name.toLower());
- // out() << "<hr />\n";
out() << "<a name=\"" << ref << "\"></a>" << divNavTop << "\n";
out() << "<h2 id=\"" << ref << "\">" << protectEnc(name) << "</h2>\n";
generateSection(s->reimplementedMembers(), aggregate, marker);
@@ -1473,7 +1471,6 @@ void HtmlGenerator::generateCppReferencePage(Node* node, CodeMarker* marker)
if (!aggregate->doc().isEmpty()) {
generateExtractionMark(aggregate, DetailedDescriptionMark);
- //out() << "<hr />\n"
out() << "<div class=\"descr\">\n" // QTBUG-9504
<< "<h2 id=\"" << detailsRef << "\">" << "Detailed Description" << "</h2>\n";
generateBody(aggregate, marker);
@@ -1485,6 +1482,7 @@ void HtmlGenerator::generateCppReferencePage(Node* node, CodeMarker* marker)
s = detailsSections->constBegin();
while (s != detailsSections->constEnd()) {
+ bool headerGenerated = false;
if (s->isEmpty()) {
++s;
continue;
@@ -1496,50 +1494,56 @@ void HtmlGenerator::generateCppReferencePage(Node* node, CodeMarker* marker)
NodeVector::ConstIterator m = s->members().constBegin();
while (m != s->members().constEnd()) {
- if ((*m)->access() != Node::Private) { // ### check necessary?
- if ((*m)->nodeType() != Node::Class)
- generateDetailedMember(*m, aggregate, marker);
- else {
- out() << "<h3> class ";
- generateFullName(*m, aggregate);
- out() << "</h3>";
- generateBrief(*m, marker, aggregate);
- }
+ if ((*m)->access() == Node::Private) { // ### check necessary?
+ ++m;
+ continue;
+ }
+ if (!headerGenerated) {
+ if (!s->divClass().isEmpty())
+ out() << "<div class=\"" << s->divClass() << "\">\n"; // QTBUG-9504
+ out() << "<h2>" << protectEnc(s->title()) << "</h2>\n";
+ headerGenerated = true;
+ }
+ if ((*m)->nodeType() != Node::Class)
+ generateDetailedMember(*m, aggregate, marker);
+ else {
+ out() << "<h3> class ";
+ generateFullName(*m, aggregate);
+ out() << "</h3>";
+ generateBrief(*m, marker, aggregate);
+ }
- QStringList names;
- names << (*m)->name();
- if ((*m)->nodeType() == Node::Function) {
- const FunctionNode *func = reinterpret_cast<const FunctionNode *>(*m);
- if (func->isSomeCtor() || func->isDtor() || func->overloadNumber() != 0)
- names.clear();
- }
- else if ((*m)->nodeType() == Node::Property) {
- const PropertyNode *prop = reinterpret_cast<const PropertyNode *>(*m);
- if (!prop->getters().isEmpty() &&
- !names.contains(prop->getters().first()->name()))
- names << prop->getters().first()->name();
- if (!prop->setters().isEmpty())
- names << prop->setters().first()->name();
- if (!prop->resetters().isEmpty())
- names << prop->resetters().first()->name();
- if (!prop->notifiers().isEmpty())
- names << prop->notifiers().first()->name();
- }
- else if ((*m)->nodeType() == Node::Enum) {
- const EnumNode *enume = reinterpret_cast<const EnumNode*>(*m);
- if (enume->flagsType())
- names << enume->flagsType()->name();
-
- foreach (const QString &enumName,
- enume->doc().enumItemNames().toSet() -
- enume->doc().omitEnumItemNames().toSet())
- names << plainCode(marker->markedUpEnumValue(enumName,
- enume));
- }
+ QStringList names;
+ names << (*m)->name();
+ if ((*m)->nodeType() == Node::Function) {
+ const FunctionNode *func = reinterpret_cast<const FunctionNode *>(*m);
+ if (func->isSomeCtor() || func->isDtor() || func->overloadNumber() != 0)
+ names.clear();
+ } else if ((*m)->nodeType() == Node::Property) {
+ const PropertyNode *prop = reinterpret_cast<const PropertyNode *>(*m);
+ if (!prop->getters().isEmpty() &&
+ !names.contains(prop->getters().first()->name()))
+ names << prop->getters().first()->name();
+ if (!prop->setters().isEmpty())
+ names << prop->setters().first()->name();
+ if (!prop->resetters().isEmpty())
+ names << prop->resetters().first()->name();
+ if (!prop->notifiers().isEmpty())
+ names << prop->notifiers().first()->name();
+ } else if ((*m)->nodeType() == Node::Enum) {
+ const EnumNode *enume = reinterpret_cast<const EnumNode*>(*m);
+ if (enume->flagsType())
+ names << enume->flagsType()->name();
+
+ foreach (const QString &enumName,
+ enume->doc().enumItemNames().toSet() -
+ enume->doc().omitEnumItemNames().toSet())
+ names << plainCode(marker->markedUpEnumValue(enumName,
+ enume));
}
++m;
}
- if (!s->divClass().isEmpty())
+ if (headerGenerated && !s->divClass().isEmpty())
out() << "</div>\n"; // QTBUG-9504
++s;
}
diff --git a/src/qdoc/node.cpp b/src/qdoc/node.cpp
index 6e6202f76..976ee5689 100644
--- a/src/qdoc/node.cpp
+++ b/src/qdoc/node.cpp
@@ -948,7 +948,7 @@ Node *Aggregate::findChildNode(const QString& name, Node::Genus genus, int findF
} else {
NodeList nodes = childMap_.values(name);
if (!nodes.isEmpty()) {
- for (int i=0; i<nodes.size(); ++i) {
+ for (int i = 0; i < nodes.size(); ++i) {
Node* node = nodes.at(i);
if (genus == node->genus()) {
if (findFlags & TypesOnly) {
@@ -960,7 +960,8 @@ Node *Aggregate::findChildNode(const QString& name, Node::Genus genus, int findF
&& !node->isJsBasicType()
&& !node->isEnumType())
continue;
- }
+ } else if (findFlags & IgnoreModules && node->isModule())
+ continue;
return node;
}
}
diff --git a/src/qdoc/qdocdatabase.h b/src/qdoc/qdocdatabase.h
index 9e53dde53..deb554abe 100644
--- a/src/qdoc/qdocdatabase.h
+++ b/src/qdoc/qdocdatabase.h
@@ -51,7 +51,8 @@ class QDocDatabase;
enum FindFlag {
SearchBaseClasses = 0x1,
SearchEnumValues = 0x2,
- TypesOnly = 0x4
+ TypesOnly = 0x4,
+ IgnoreModules = 0x8
};
class QDocForest
diff --git a/src/qdoc/tree.cpp b/src/qdoc/tree.cpp
index ea3950a9e..4a7b15b09 100644
--- a/src/qdoc/tree.cpp
+++ b/src/qdoc/tree.cpp
@@ -885,7 +885,11 @@ const Node* Tree::findNode(const QStringList& path,
if (node == 0 || !node->isAggregate())
break;
- const Node* next = static_cast<const Aggregate*>(node)->findChildNode(path.at(i), genus, findFlags);
+ // Clear the TypesOnly flag until the last path segment, as e.g. namespaces are not types.
+ // We also ignore module nodes as they are not aggregates and thus have no children.
+ int tmpFlags = (i < path.size() - 1) ? (findFlags & ~TypesOnly) | IgnoreModules : findFlags;
+
+ const Node* next = static_cast<const Aggregate*>(node)->findChildNode(path.at(i), genus, tmpFlags);
if (!next && (findFlags & SearchEnumValues) && i == path.size()-1) {
next = static_cast<const Aggregate*>(node)->findEnumNodeForValue(path.at(i));
}
@@ -893,7 +897,7 @@ const Node* Tree::findNode(const QStringList& path,
node->isClass() && (findFlags & SearchBaseClasses)) {
NodeList baseClasses = allBaseClasses(static_cast<const ClassNode*>(node));
foreach (const Node* baseClass, baseClasses) {
- next = static_cast<const Aggregate*>(baseClass)->findChildNode(path.at(i), genus, findFlags);
+ next = static_cast<const Aggregate*>(baseClass)->findChildNode(path.at(i), genus, tmpFlags);
if (!next && (findFlags & SearchEnumValues) && i == path.size() - 1)
next = static_cast<const Aggregate*>(baseClass)->findEnumNodeForValue(path.at(i));
if (next) {
diff --git a/src/qtattributionsscanner/qdocgenerator.cpp b/src/qtattributionsscanner/qdocgenerator.cpp
index 6cab72e6e..882875ff5 100644
--- a/src/qtattributionsscanner/qdocgenerator.cpp
+++ b/src/qtattributionsscanner/qdocgenerator.cpp
@@ -143,7 +143,7 @@ static void generate(QTextStream &out, const Package &package, const QDir &baseD
tr("Path %1 : cannot open license file %2.")
.arg(QDir::toNativeSeparators(package.path))
.arg(QDir::toNativeSeparators(package.licenseFile))
- ) << "\n";
+ ) << "*/\n";
return;
}
out << "\\badcode\n";
diff --git a/src/shared/winutils/qmlutils.cpp b/src/shared/winutils/qmlutils.cpp
index 414446499..6e8d5192b 100644
--- a/src/shared/winutils/qmlutils.cpp
+++ b/src/shared/winutils/qmlutils.cpp
@@ -51,7 +51,7 @@ QString QmlImportScanResult::Module::installPath(const QString &root) const
const int lastSlashPos = relativePath.lastIndexOf(QLatin1Char('/'));
if (lastSlashPos != -1) {
result += QLatin1Char('/');
- result += relativePath.left(lastSlashPos);
+ result += relativePath.leftRef(lastSlashPos);
}
return result;
}
@@ -116,7 +116,7 @@ QmlImportScanResult runQmlImportScanner(const QString &directory, const QStringL
+ QStringLiteral(": ") + QString::fromLocal8Bit(stdErr);
return result;
}
- QJsonParseError jsonParseError;
+ QJsonParseError jsonParseError{};
const QJsonDocument data = QJsonDocument::fromJson(stdOut, &jsonParseError);
if (data.isNull() ) {
*errorMessage = binary + QStringLiteral(" returned invalid JSON output: ")
diff --git a/src/shared/winutils/qmlutils.h b/src/shared/winutils/qmlutils.h
index a05007103..87e6ca132 100644
--- a/src/shared/winutils/qmlutils.h
+++ b/src/shared/winutils/qmlutils.h
@@ -47,10 +47,9 @@ struct QmlImportScanResult {
QString relativePath;
};
- QmlImportScanResult() : ok(false) {}
void append(const QmlImportScanResult &other);
- bool ok;
+ bool ok = false;
QList<Module> modules;
QStringList plugins;
};
diff --git a/src/shared/winutils/utils.cpp b/src/shared/winutils/utils.cpp
index cdf017715..00a205438 100644
--- a/src/shared/winutils/utils.cpp
+++ b/src/shared/winutils/utils.cpp
@@ -493,8 +493,6 @@ QString findInPath(const QString &file)
const char *qmakeInfixKey = "QT_INFIX";
-QMap<QString, QString> queryQMakeAll(QString *errorMessage);
-
QMap<QString, QString> queryQMakeAll(QString *errorMessage)
{
QByteArray stdOut;
@@ -819,12 +817,12 @@ inline void determineDebugAndDependentLibs(const ImageNtHeader *nth, const void
{
const bool hasDebugEntry = nth->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size;
QStringList dependentLibraries;
- if (dependentLibrariesIn || (isDebugIn && hasDebugEntry && !isMinGW))
+ if (dependentLibrariesIn || (isDebugIn != nullptr && hasDebugEntry && !isMinGW))
dependentLibraries = readImportSections(nth, fileMemory, errorMessage);
if (dependentLibrariesIn)
*dependentLibrariesIn = dependentLibraries;
- if (isDebugIn) {
+ if (isDebugIn != nullptr) {
if (isMinGW) {
// Use logic that's used e.g. in objdump / pfd library
*isDebugIn = !(nth->FileHeader.Characteristics & IMAGE_FILE_DEBUG_STRIPPED);
@@ -840,7 +838,7 @@ inline void determineDebugAndDependentLibs(const ImageNtHeader *nth, const void
// and debug flags.
bool readPeExecutable(const QString &peExecutableFileName, QString *errorMessage,
QStringList *dependentLibrariesIn, unsigned *wordSizeIn,
- bool *isDebugIn, bool isMinGW)
+ bool *isDebugIn, bool isMinGW, unsigned short *machineArchIn)
{
bool result = false;
HANDLE hFile = NULL;
@@ -890,6 +888,9 @@ bool readPeExecutable(const QString &peExecutableFileName, QString *errorMessage
fileMemory, isMinGW, dependentLibrariesIn, isDebugIn, errorMessage);
}
+ if (machineArchIn)
+ *machineArchIn = ntHeaders->FileHeader.Machine;
+
result = true;
if (optVerboseLevel > 1) {
std::wcout << __FUNCTION__ << ": " << QDir::toNativeSeparators(peExecutableFileName)
@@ -970,7 +971,7 @@ QString findD3dCompiler(Platform platform, const QString &qtBinDir, unsigned wor
#else // Q_OS_WIN
bool readPeExecutable(const QString &, QString *errorMessage,
- QStringList *, unsigned *, bool *, bool)
+ QStringList *, unsigned *, bool *, bool, unsigned short *)
{
*errorMessage = QStringLiteral("Not implemented.");
return false;
@@ -1032,4 +1033,23 @@ bool patchQtCore(const QString &path, QString *errorMessage)
return true;
}
+#ifdef Q_OS_WIN
+QString getArchString(unsigned short machineArch)
+{
+ switch (machineArch) {
+ case IMAGE_FILE_MACHINE_I386:
+ return QStringLiteral("x86");
+ case IMAGE_FILE_MACHINE_ARM:
+ return QStringLiteral("arm");
+ case IMAGE_FILE_MACHINE_AMD64:
+ return QStringLiteral("x64");
+ case IMAGE_FILE_MACHINE_ARM64:
+ return QStringLiteral("arm64");
+ default:
+ break;
+ }
+ return QString();
+}
+#endif // Q_OS_WIN
+
QT_END_NAMESPACE
diff --git a/src/shared/winutils/utils.h b/src/shared/winutils/utils.h
index a5e6f01f7..5552a3665 100644
--- a/src/shared/winutils/utils.h
+++ b/src/shared/winutils/utils.h
@@ -82,8 +82,8 @@ inline std::wostream &operator<<(std::wostream &str, const QString &s)
// Container class for JSON output
class JsonOutput
{
- typedef QPair<QString, QString> SourceTargetMapping;
- typedef QList<SourceTargetMapping> SourceTargetMappings;
+ using SourceTargetMapping = QPair<QString, QString>;
+ using SourceTargetMappings = QList<SourceTargetMapping>;
public:
void addFile(const QString &source, const QString &target)
@@ -185,21 +185,28 @@ bool runElevatedBackgroundProcess(const QString &binary, const QStringList &args
bool readPeExecutable(const QString &peExecutableFileName, QString *errorMessage,
QStringList *dependentLibraries = 0, unsigned *wordSize = 0,
- bool *isDebug = 0, bool isMinGW = false);
+ bool *isDebug = 0, bool isMinGW = false, unsigned short *machineArch = nullptr);
bool readElfExecutable(const QString &elfExecutableFileName, QString *errorMessage,
QStringList *dependentLibraries = 0, unsigned *wordSize = 0,
bool *isDebug = 0);
inline bool readExecutable(const QString &executableFileName, Platform platform,
QString *errorMessage, QStringList *dependentLibraries = 0,
- unsigned *wordSize = 0, bool *isDebug = 0)
+ unsigned *wordSize = 0, bool *isDebug = 0, unsigned short *machineArch = nullptr)
{
return platform == Unix ?
readElfExecutable(executableFileName, errorMessage, dependentLibraries, wordSize, isDebug) :
readPeExecutable(executableFileName, errorMessage, dependentLibraries, wordSize, isDebug,
- (platform == WindowsDesktopMinGW));
+ (platform == WindowsDesktopMinGW), machineArch);
}
+#ifdef Q_OS_WIN
+# if !defined(IMAGE_FILE_MACHINE_ARM64)
+# define IMAGE_FILE_MACHINE_ARM64 0xAA64
+# endif
+QString getArchString (unsigned short machineArch);
+#endif // Q_OS_WIN
+
// Return dependent modules of executable files.
inline QStringList findDependentLibraries(const QString &executableFileName, Platform platform, QString *errorMessage)
diff --git a/src/windeployqt/main.cpp b/src/windeployqt/main.cpp
index 738887c0f..247749aaa 100644
--- a/src/windeployqt/main.cpp
+++ b/src/windeployqt/main.cpp
@@ -40,6 +40,7 @@
#include <QtCore/QOperatingSystemVersion>
#include <QtCore/QSharedPointer>
#include <QtCore/QVector>
+#include <QtCore/qt_windows.h>
#include <algorithm>
#include <iostream>
@@ -180,12 +181,11 @@ static inline QString webProcessBinary(const char *binaryName, Platform p)
static QByteArray formatQtModules(quint64 mask, bool option = false)
{
QByteArray result;
- const size_t qtModulesCount = sizeof(qtModuleEntries)/sizeof(QtModuleEntry);
- for (size_t i = 0; i < qtModulesCount; ++i) {
- if (mask & qtModuleEntries[i].module) {
+ for (const auto &qtModule : qtModuleEntries) {
+ if (mask & qtModule.module) {
if (!result.isEmpty())
result.append(' ');
- result.append(option ? qtModuleEntries[i].option : qtModuleEntries[i].libraryName);
+ result.append(option ? qtModule.option : qtModule.libraryName);
}
}
return result;
@@ -311,9 +311,8 @@ enum CommandLineParseFlag {
static inline int parseArguments(const QStringList &arguments, QCommandLineParser *parser,
Options *options, QString *errorMessage)
{
- typedef QSharedPointer<QCommandLineOption> CommandLineOptionPtr;
- typedef QPair<CommandLineOptionPtr, quint64> OptionMaskPair;
- typedef QVector<OptionMaskPair> OptionMaskVector;
+ using CommandLineOptionPtr = QSharedPointer<QCommandLineOption>;
+ using OptionPtrVector = QVector<CommandLineOptionPtr>;
parser->setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions);
parser->setApplicationDescription(QStringLiteral("Qt Deploy Tool ") + QLatin1String(QT_VERSION_STR)
@@ -450,21 +449,22 @@ static inline int parseArguments(const QStringList &arguments, QCommandLineParse
parser->addPositionalArgument(QStringLiteral("[files]"),
QStringLiteral("Binaries or directory containing the binary."));
- OptionMaskVector enabledModules;
- OptionMaskVector disabledModules;
- const size_t qtModulesCount = sizeof(qtModuleEntries)/sizeof(QtModuleEntry);
- for (size_t i = 0; i < qtModulesCount; ++i) {
+ OptionPtrVector enabledModuleOptions;
+ OptionPtrVector disabledModuleOptions;
+ const int qtModulesCount = int(sizeof(qtModuleEntries) / sizeof(QtModuleEntry));
+ enabledModuleOptions.reserve(qtModulesCount);
+ disabledModuleOptions.reserve(qtModulesCount);
+ for (int i = 0; i < qtModulesCount; ++i) {
const QString option = QLatin1String(qtModuleEntries[i].option);
const QString name = QLatin1String(qtModuleEntries[i].libraryName);
const QString enabledDescription = QStringLiteral("Add ") + name + QStringLiteral(" module.");
CommandLineOptionPtr enabledOption(new QCommandLineOption(option, enabledDescription));
parser->addOption(*enabledOption.data());
- enabledModules.push_back(OptionMaskPair(enabledOption, qtModuleEntries[i].module));
-
+ enabledModuleOptions.append(enabledOption);
const QString disabledDescription = QStringLiteral("Remove ") + name + QStringLiteral(" module.");
CommandLineOptionPtr disabledOption(new QCommandLineOption(QStringLiteral("no-") + option,
disabledDescription));
- disabledModules.push_back(OptionMaskPair(disabledOption, qtModuleEntries[i].module));
+ disabledModuleOptions.append(disabledOption);
parser->addOption(*disabledOption.data());
}
@@ -540,11 +540,11 @@ static inline int parseArguments(const QStringList &arguments, QCommandLineParse
options->patchQt = !parser->isSet(noPatchQtOption);
- for (size_t i = 0; i < qtModulesCount; ++i) {
- if (parser->isSet(*enabledModules.at(int(i)).first.data()))
- options->additionalLibraries |= enabledModules.at(int(i)).second;
- if (parser->isSet(*disabledModules.at(int(i)).first.data()))
- options->disabledLibraries |= disabledModules.at(int(i)).second;
+ for (int i = 0; i < qtModulesCount; ++i) {
+ if (parser->isSet(*enabledModuleOptions.at(i)))
+ options->additionalLibraries |= qtModuleEntries[i].module;
+ if (parser->isSet(*disabledModuleOptions.at(i)))
+ options->disabledLibraries |= qtModuleEntries[i].module;
}
// Add some dependencies
@@ -689,13 +689,13 @@ static inline bool isQtModule(const QString &libName)
// Helper for recursively finding all dependent Qt libraries.
static bool findDependentQtLibraries(const QString &qtBinDir, const QString &binary, Platform platform,
QString *errorMessage, QStringList *result,
- unsigned *wordSize = 0, bool *isDebug = 0,
+ unsigned *wordSize = 0, bool *isDebug = 0, unsigned short *machineArch = 0,
int *directDependencyCount = 0, int recursionDepth = 0)
{
QStringList dependentLibs;
if (directDependencyCount)
*directDependencyCount = 0;
- if (!readExecutable(binary, platform, errorMessage, &dependentLibs, wordSize, isDebug)) {
+ if (!readExecutable(binary, platform, errorMessage, &dependentLibs, wordSize, isDebug, machineArch)) {
errorMessage->prepend(QLatin1String("Unable to find dependent libraries of ") +
QDir::toNativeSeparators(binary) + QLatin1String(" :"));
return false;
@@ -715,7 +715,7 @@ static bool findDependentQtLibraries(const QString &qtBinDir, const QString &bin
*directDependencyCount = end - start;
// Recurse
for (int i = start; i < end; ++i)
- if (!findDependentQtLibraries(qtBinDir, result->at(i), platform, errorMessage, result, 0, 0, 0, recursionDepth + 1))
+ if (!findDependentQtLibraries(qtBinDir, result->at(i), platform, errorMessage, result, 0, 0, 0, 0, recursionDepth + 1))
return false;
return true;
}
@@ -838,10 +838,9 @@ static const PluginModuleMapping pluginModuleMappings[] =
static inline quint64 qtModuleForPlugin(const QString &subDirName)
{
- const PluginModuleMapping *end = pluginModuleMappings
- + sizeof(pluginModuleMappings) / sizeof(pluginModuleMappings[0]);
- const PluginModuleMapping *result =
- std::find_if(pluginModuleMappings, end,
+ const auto end = std::end(pluginModuleMappings);
+ const auto result =
+ std::find_if(std::begin(pluginModuleMappings), end,
[&subDirName] (const PluginModuleMapping &m) { return subDirName == QLatin1String(m.directoryName); });
return result != end ? result->module : 0; // "designer"
}
@@ -860,12 +859,11 @@ static quint64 qtModule(QString module, const QString &infix)
if (endPos > 0)
module.truncate(endPos);
// That should leave us with 'Qt5Core<d>'.
- const size_t qtModulesCount = sizeof(qtModuleEntries)/sizeof(QtModuleEntry);
- for (size_t i = 0; i < qtModulesCount; ++i) {
- const QLatin1String libraryName(qtModuleEntries[i].libraryName);
+ for (const auto &qtModule : qtModuleEntries) {
+ const QLatin1String libraryName(qtModule.libraryName);
if (module == libraryName
|| (module.size() == libraryName.size() + 1 && module.startsWith(libraryName))) {
- return qtModuleEntries[i].module;
+ return qtModule.module;
}
}
return 0;
@@ -954,10 +952,9 @@ QStringList findQtPlugins(quint64 *usedQtModules, quint64 disabledQtModules,
static QStringList translationNameFilters(quint64 modules, const QString &prefix)
{
QStringList result;
- const size_t qtModulesCount = sizeof(qtModuleEntries)/sizeof(QtModuleEntry);
- for (size_t i = 0; i < qtModulesCount; ++i) {
- if ((qtModuleEntries[i].module & modules) && qtModuleEntries[i].translation) {
- const QString name = QLatin1String(qtModuleEntries[i].translation) +
+ for (const auto &qtModule : qtModuleEntries) {
+ if ((qtModule.module & modules) && qtModule.translation) {
+ const QString name = QLatin1String(qtModule.translation) +
QLatin1Char('_') + prefix + QStringLiteral(".qm");
if (!result.contains(name))
result.push_back(name);
@@ -1048,6 +1045,7 @@ static QString libraryPath(const QString &libraryLocation, const char *name,
}
static QString vcDebugRedistDir() { return QStringLiteral("Debug_NonRedist"); }
+static QString onecoreRedistDir() { return QStringLiteral("onecore"); }
static QString vcRedistDir()
{
@@ -1089,7 +1087,7 @@ static QString vcRedistDir()
return QString();
}
-static QStringList compilerRunTimeLibs(Platform platform, bool isDebug, unsigned wordSize)
+static QStringList compilerRunTimeLibs(Platform platform, bool isDebug, unsigned short machineArch)
{
QStringList result;
switch (platform) {
@@ -1103,9 +1101,8 @@ static QStringList compilerRunTimeLibs(Platform platform, bool isDebug, unsigned
const QString binPath = QFileInfo(gcc).absolutePath();
QStringList filters;
const QString suffix = QLatin1Char('*') + sharedLibrarySuffix(platform);
- const size_t count = sizeof(minGwRuntimes) / sizeof(minGwRuntimes[0]);
- for (size_t i = 0; i < count; ++i)
- filters.append(QLatin1String(minGwRuntimes[i]) + suffix);
+ for (auto minGwRuntime : minGwRuntimes)
+ filters.append(QLatin1String(minGwRuntime) + suffix);
const QFileInfoList &dlls = QDir(binPath).entryInfoList(filters, QDir::Files);
for (const QFileInfo &dllFi : dlls)
result.append(dllFi.absoluteFilePath());
@@ -1117,10 +1114,10 @@ static QStringList compilerRunTimeLibs(Platform platform, bool isDebug, unsigned
break;
QStringList redistFiles;
QDir vcRedistDir(vcRedistDirName);
- const QString wordSizeString(QLatin1String(wordSize > 32 ? "x64" : "x86"));
+ const QString machineArchString = getArchString(machineArch);
if (isDebug) {
// Append DLLs from Debug_NonRedist\x??\Microsoft.VC<version>.DebugCRT.
- if (vcRedistDir.cd(vcDebugRedistDir()) && vcRedistDir.cd(wordSizeString)) {
+ if (vcRedistDir.cd(vcDebugRedistDir()) && vcRedistDir.cd(machineArchString)) {
const QStringList names = vcRedistDir.entryList(QStringList(QStringLiteral("Microsoft.VC*.DebugCRT")), QDir::Dirs);
if (!names.isEmpty() && vcRedistDir.cd(names.first())) {
const QFileInfoList &dlls = vcRedistDir.entryInfoList(QStringList(QLatin1String("*.dll")));
@@ -1134,10 +1131,10 @@ static QStringList compilerRunTimeLibs(Platform platform, bool isDebug, unsigned
if (!countryCodes.isEmpty()) // Pre MSVC2017
releaseRedistDir += QLatin1Char('/') + countryCodes.constFirst();
QFileInfo fi(releaseRedistDir + QLatin1Char('/') + QStringLiteral("vc_redist.")
- + wordSizeString + QStringLiteral(".exe"));
+ + machineArchString + QStringLiteral(".exe"));
if (!fi.isFile()) { // Pre MSVC2017/15.5
fi.setFile(releaseRedistDir + QLatin1Char('/') + QStringLiteral("vcredist_")
- + wordSizeString + QStringLiteral(".exe"));
+ + machineArchString + QStringLiteral(".exe"));
}
if (fi.isFile())
redistFiles.append(fi.absoluteFilePath());
@@ -1190,24 +1187,6 @@ static bool updateLibrary(const QString &sourceFileName, const QString &targetDi
return true;
}
-// Check for a Qt Quick Controls import path and return the version.
-// 'QtQuick/Controls' ==> 1, or 'QtQuick/Controls.2' ==> 2.
-static inline int quickControlsImportPath(const QString &ip)
-{
- if (ip.contains(QLatin1String("Qt/labs/calendar"))
- || ip.contains(QLatin1String("Qt/labs/folderlistmodel"))
- || ip.contains(QLatin1String("Qt/labs/settings"))
- || ip.contains(QLatin1String("QtQuick/Templates.2"))
- || ip.contains(QLatin1String("QtQuick/Controls.2"))) {
- return 2;
- }
- if (ip.endsWith(QLatin1String("QtQuick/Dialogs")) || ip.contains(QLatin1String("QtQuick/Dialogs/"))
- || ip.contains(QLatin1String("QtQuick/Controls"))) {
- return 1; // Dialogs only in v1, so far; no version number on directory: v1.
- }
- return 0; // Non-controls import
-}
-
static DeployResult deploy(const Options &options,
const QMap<QString, QString> &qmakeVariables,
QString *errorMessage)
@@ -1228,9 +1207,10 @@ static DeployResult deploy(const Options &options,
QStringList dependentQtLibs;
bool detectedDebug;
unsigned wordSize;
+ unsigned short machineArch;
int directDependencyCount = 0;
if (!findDependentQtLibraries(libraryLocation, options.binaries.first(), options.platform, errorMessage, &dependentQtLibs, &wordSize,
- &detectedDebug, &directDependencyCount)) {
+ &detectedDebug, &machineArch, &directDependencyCount)) {
return result;
}
for (int b = 1; b < options.binaries.size(); ++b) {
@@ -1329,7 +1309,7 @@ static DeployResult deploy(const Options &options,
qmlScanResult.append(scanResult);
// Additional dependencies of QML plugins.
for (const QString &plugin : qAsConst(qmlScanResult.plugins)) {
- if (!findDependentQtLibraries(libraryLocation, plugin, options.platform, errorMessage, &dependentQtLibs, &wordSize, &detectedDebug))
+ if (!findDependentQtLibraries(libraryLocation, plugin, options.platform, errorMessage, &dependentQtLibs, &wordSize, &detectedDebug, &machineArch))
return result;
}
if (optVerboseLevel >= 1) {
@@ -1369,12 +1349,11 @@ static DeployResult deploy(const Options &options,
// Apply options flags and re-add library names.
QString qtGuiLibrary;
- const size_t qtModulesCount = sizeof(qtModuleEntries)/sizeof(QtModuleEntry);
- for (size_t i = 0; i < qtModulesCount; ++i) {
- if (result.deployedQtLibraries & qtModuleEntries[i].module) {
- const QString library = libraryPath(libraryLocation, qtModuleEntries[i].libraryName, qtLibInfix, options.platform, isDebug);
+ for (const auto &qtModule : qtModuleEntries) {
+ if (result.deployedQtLibraries & qtModule.module) {
+ const QString library = libraryPath(libraryLocation, qtModule.libraryName, qtLibInfix, options.platform, isDebug);
deployedQtLibraries.append(library);
- if (qtModuleEntries[i].module == QtGuiModule)
+ if (qtModule.module == QtGuiModule)
qtGuiLibrary = library;
}
}
@@ -1411,7 +1390,7 @@ static DeployResult deploy(const Options &options,
if (options.angleDetection != Options::AngleDetectionForceOff
&& (dependsOnAngle || dependsOnCombinedAngle || !dependsOnOpenGl || options.angleDetection == Options::AngleDetectionForceOn)) {
const QString combinedAngleFullPath = qtBinDir + slash + libCombinedQtAngleName;
- if (QFileInfo(combinedAngleFullPath).exists()) {
+ if (QFileInfo::exists(combinedAngleFullPath)) {
deployedQtLibraries.append(combinedAngleFullPath);
} else {
const QString libGlesFullPath = qtBinDir + slash + libGlesName;
@@ -1423,7 +1402,8 @@ static DeployResult deploy(const Options &options,
deployedQtLibraries.append(libEglFullPath);
}
// Find the system D3d Compiler matching the D3D library.
- if (options.systemD3dCompiler && !options.isWinRt()) {
+ // Any arm64 OS will be new enough to be shipped with the D3DCompiler inbox.
+ if (options.systemD3dCompiler && !options.isWinRt() && machineArch != IMAGE_FILE_MACHINE_ARM64) {
const QString d3dCompiler = findD3dCompiler(options.platform, qtBinDir, wordSize);
if (d3dCompiler.isEmpty()) {
std::wcerr << "Warning: Cannot find any version of the d3dcompiler DLL.\n";
@@ -1472,7 +1452,7 @@ static DeployResult deploy(const Options &options,
options.directory : options.libraryDirectory;
QStringList libraries = deployedQtLibraries;
if (options.compilerRunTime)
- libraries.append(compilerRunTimeLibs(options.platform, isDebug, wordSize));
+ libraries.append(compilerRunTimeLibs(options.platform, isDebug, machineArch));
for (const QString &qtLib : qAsConst(libraries)) {
if (!updateLibrary(qtLib, targetPath, options, errorMessage))
return result;
@@ -1604,8 +1584,8 @@ static bool deployWebEngineCore(const QMap<QString, QString> &qmakeVariables,
const QString resourcesTargetDir(options.directory + resourcesSubDir);
if (!createDirectory(resourcesTargetDir, errorMessage))
return false;
- for (size_t i = 0; i < sizeof(installDataFiles)/sizeof(installDataFiles[0]); ++i) {
- if (!updateFile(resourcesSourceDir + QLatin1String(installDataFiles[i]),
+ for (auto installDataFile : installDataFiles) {
+ if (!updateFile(resourcesSourceDir + QLatin1String(installDataFile),
resourcesTargetDir, options.updateFileFlags, options.json, errorMessage)) {
return false;
}
@@ -1622,21 +1602,20 @@ static bool deployWebEngineCore(const QMap<QString, QString> &qmakeVariables,
return createDirectory(options.translationsDirectory, errorMessage)
&& updateFile(translations.absoluteFilePath(), options.translationsDirectory,
options.updateFileFlags, options.json, errorMessage);
- } else {
- // Translations have been turned off, but QtWebEngine needs at least one.
- const QFileInfo enUSpak(translations.filePath() + QStringLiteral("/en-US.pak"));
- if (!enUSpak.exists()) {
- std::wcerr << "Warning: Cannot find "
- << QDir::toNativeSeparators(enUSpak.absoluteFilePath()) << ".\n";
- return true;
- }
- const QString webEngineTranslationsDir = options.translationsDirectory + QLatin1Char('/')
- + translations.fileName();
- if (!createDirectory(webEngineTranslationsDir, errorMessage))
- return false;
- return updateFile(enUSpak.absoluteFilePath(), webEngineTranslationsDir,
- options.updateFileFlags, options.json, errorMessage);
}
+ // Translations have been turned off, but QtWebEngine needs at least one.
+ const QFileInfo enUSpak(translations.filePath() + QStringLiteral("/en-US.pak"));
+ if (!enUSpak.exists()) {
+ std::wcerr << "Warning: Cannot find "
+ << QDir::toNativeSeparators(enUSpak.absoluteFilePath()) << ".\n";
+ return true;
+ }
+ const QString webEngineTranslationsDir = options.translationsDirectory + QLatin1Char('/')
+ + translations.fileName();
+ if (!createDirectory(webEngineTranslationsDir, errorMessage))
+ return false;
+ return updateFile(enUSpak.absoluteFilePath(), webEngineTranslationsDir,
+ options.updateFileFlags, options.json, errorMessage);
}
int main(int argc, char **argv)
diff --git a/src/winrtrunner/appxlocalengine.cpp b/src/winrtrunner/appxlocalengine.cpp
index e255f0a98..69bc39919 100644
--- a/src/winrtrunner/appxlocalengine.cpp
+++ b/src/winrtrunner/appxlocalengine.cpp
@@ -690,6 +690,31 @@ bool AppxLocalEngine::setLoopbackExemptServerEnabled(bool enabled)
return true;
}
+bool AppxLocalEngine::setLoggingRules(const QByteArray &rules)
+{
+ qCDebug(lcWinRtRunner) << __FUNCTION__;
+
+ QDir loggingIniDir(devicePath(QLatin1String("QtProject")));
+ if (!loggingIniDir.exists() && !loggingIniDir.mkpath(QStringLiteral("."))) {
+ qCWarning(lcWinRtRunner) << "Could not create" << loggingIniDir;
+ return false;
+ }
+ QFile loggingIniFile(loggingIniDir.absolutePath().append(QLatin1String("/qtlogging.ini")));
+ if (loggingIniFile.exists() && !loggingIniFile.remove()) {
+ qCWarning(lcWinRtRunner) << loggingIniFile << "already exists.";
+ return false;
+ }
+ if (!loggingIniFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
+ qCWarning(lcWinRtRunner) << "Could not open" << loggingIniFile << "for writing.";
+ return false;
+ }
+
+ QTextStream stream(&loggingIniFile);
+ stream << "[Rules]\n" << rules;
+
+ return true;
+}
+
bool AppxLocalEngine::suspend()
{
diff --git a/src/winrtrunner/appxlocalengine.h b/src/winrtrunner/appxlocalengine.h
index 291149bd3..0049b6ba4 100644
--- a/src/winrtrunner/appxlocalengine.h
+++ b/src/winrtrunner/appxlocalengine.h
@@ -64,6 +64,7 @@ public:
bool disableDebugging() override;
bool setLoopbackExemptClientEnabled(bool enabled) override;
bool setLoopbackExemptServerEnabled(bool enabled) override;
+ bool setLoggingRules(const QByteArray &rules) override;
bool suspend() override;
bool waitForFinished(int secs) override;
bool stop() override;
diff --git a/src/winrtrunner/appxphoneengine.cpp b/src/winrtrunner/appxphoneengine.cpp
index e45d007e4..39c3b2712 100644
--- a/src/winrtrunner/appxphoneengine.cpp
+++ b/src/winrtrunner/appxphoneengine.cpp
@@ -471,6 +471,12 @@ bool AppxPhoneEngine::setLoopbackExemptServerEnabled(bool)
return false;
}
+bool AppxPhoneEngine::setLoggingRules(const QByteArray &)
+{
+ qCDebug(lcWinRtRunner) << __FUNCTION__;
+ return false;
+}
+
bool AppxPhoneEngine::suspend()
{
qCDebug(lcWinRtRunner) << __FUNCTION__;
diff --git a/src/winrtrunner/appxphoneengine.h b/src/winrtrunner/appxphoneengine.h
index 641bf4653..b462e797f 100644
--- a/src/winrtrunner/appxphoneengine.h
+++ b/src/winrtrunner/appxphoneengine.h
@@ -64,6 +64,7 @@ public:
bool disableDebugging() override;
bool setLoopbackExemptClientEnabled(bool enabled) override;
bool setLoopbackExemptServerEnabled(bool enabled) override;
+ bool setLoggingRules(const QByteArray &rules) override;
bool suspend() override;
bool waitForFinished(int secs) override;
bool stop() override;
diff --git a/src/winrtrunner/main.cpp b/src/winrtrunner/main.cpp
index db22b4461..bf4e8fabf 100644
--- a/src/winrtrunner/main.cpp
+++ b/src/winrtrunner/main.cpp
@@ -40,6 +40,7 @@
#include <QtCore/QCommandLineParser>
#include <QtCore/QCoreApplication>
#include <QtCore/QDir>
+#include <QtCore/QRegExp>
#include <QtCore/QStringList>
#include <QtCore/QMap>
#include <QtCore/QLoggingCategory>
@@ -52,6 +53,23 @@ QT_USE_NAMESPACE
int main(int argc, char *argv[])
{
+ // If logging rules are set via env variable, we pass these to the application we are running.
+ // winrtrunner behaves different from other applications in the regard that its logging rules
+ // have to be enabled explicitly. Setting "*=true" will not enable extended logging. Reason is
+ // CI setting "*=true" if an auto test fails and additional winrtrunner output might just
+ // confuse users.
+ const QByteArray loggingRules = qgetenv("QT_LOGGING_RULES");
+ const QList<QByteArray> rules = loggingRules.split(';');
+ QRegExp runnerExp(QLatin1String("^qt\\.winrtrunner.*\\s*=\\s*true\\s*$"));
+ bool runnerRuleFound = false;
+ for (const QByteArray &rule : rules) {
+ if (runnerExp.indexIn(QLatin1String(rule)) != -1) {
+ runnerRuleFound = true;
+ break;
+ }
+ }
+ if (!runnerRuleFound)
+ qunsetenv("QT_LOGGING_RULES");
QCoreApplication a(argc, argv);
QCommandLineParser parser;
parser.setApplicationDescription(QLatin1String("winrtrunner installs, runs, and collects test "
@@ -118,7 +136,7 @@ int main(int argc, char *argv[])
QCommandLineOption deviceOption(QStringLiteral("device"),
QLatin1String("Specifies the device to target as a device name "
- " or index. Use --list-devices to find available "
+ "or index. Use --list-devices to find available "
"devices. The default device is the first device "
"found for the active run profile."),
QStringLiteral("name|index"));
@@ -282,6 +300,11 @@ int main(int argc, char *argv[])
return ignoreErrors ? 0 : 3;
}
+ if (!loggingRules.isNull() && !runner.setLoggingRules(loggingRules)) {
+ qCDebug(lcWinRtRunner) << "Could not set logging rules, exiting with code 3.";
+ return ignoreErrors ? 0 : 3;
+ }
+
if (parser.isSet(debugOption)) {
const QString &debuggerExecutable = parser.value(debugOption);
const QString &debuggerArguments = parser.value(debuggerArgumentsOption);
diff --git a/src/winrtrunner/runner.cpp b/src/winrtrunner/runner.cpp
index 9794fd605..e816d9baa 100644
--- a/src/winrtrunner/runner.cpp
+++ b/src/winrtrunner/runner.cpp
@@ -233,6 +233,14 @@ bool Runner::setLoopbackExemptServerEnabled(bool enabled)
return d->engine->setLoopbackExemptServerEnabled(enabled);
}
+bool Runner::setLoggingRules(const QByteArray &rules)
+{
+ Q_D(Runner);
+ Q_ASSERT(d->engine);
+
+ return d->engine->setLoggingRules(rules);
+}
+
bool Runner::suspend()
{
Q_D(Runner);
diff --git a/src/winrtrunner/runner.h b/src/winrtrunner/runner.h
index 743156154..00b251be8 100644
--- a/src/winrtrunner/runner.h
+++ b/src/winrtrunner/runner.h
@@ -70,6 +70,7 @@ public:
bool disableDebugging();
bool setLoopbackExemptClientEnabled(bool enabled);
bool setLoopbackExemptServerEnabled(bool enabled);
+ bool setLoggingRules(const QByteArray &rules);
bool suspend();
bool stop();
bool wait(int maxWaitTime = 0);
diff --git a/src/winrtrunner/runnerengine.h b/src/winrtrunner/runnerengine.h
index 4cdd8f36f..44565c46c 100644
--- a/src/winrtrunner/runnerengine.h
+++ b/src/winrtrunner/runnerengine.h
@@ -55,6 +55,7 @@ public:
virtual bool disableDebugging() = 0;
virtual bool setLoopbackExemptClientEnabled(bool enabled) = 0;
virtual bool setLoopbackExemptServerEnabled(bool enabled) = 0;
+ virtual bool setLoggingRules(const QByteArray &rules) = 0;
virtual bool suspend() = 0;
virtual bool waitForFinished(int secs) = 0;
virtual bool stop() = 0;