Merge remote-tracking branch 'origin/4.14'

Conflicts:
	src/plugins/mcusupport/mcusupportoptions.cpp
	src/plugins/qmldesigner/assetexporterplugin/componentexporter.cpp

Change-Id: I337d1b86f54ad4433a3ed0d73e2011654ef6b950
This commit is contained in:
Eike Ziller
2021-02-02 12:20:00 +01:00
17 changed files with 339 additions and 63 deletions

111
dist/changes-4.14.1.md vendored Normal file
View File

@@ -0,0 +1,111 @@
Qt Creator 4.14.1
=================
Qt Creator version 4.14.1 contains bug fixes.
The most important changes are listed in this document. For a complete
list of changes, see the Git log for the Qt Creator sources that
you can check out from the public Git repository. For example:
git clone git://code.qt.io/qt-creator/qt-creator.git
git log --cherry-pick --pretty=oneline origin/v4.14.0..v4.14.1
General
-------
* Fixed copying to clipboard from JavaScript locator filter
### Building Qt Creator with CMake
* Made it easier to build against separate litehtml (QTCREATORBUG-25144)
* Made it possible to adapt install layout for Linux distributions
(QTCREATORBUG-25142)
* Fixed building and running against system LLVM (QTCREATORBUG-25147)
Editing
-------
* Fixed search result highlighting for overlapping results (QTCREATORBUG-25237)
### C++
* Added support for `BINDABLE` in `Q_PROPERTY`
* Fixed loading `ClangFormat` plugin on Linux distributions with software
rendering (QTCREATORBUG-24998)
* Fixed hanging `Follow Symbol` (QTCREATORBUG-25193)
* Fixed freeze in global indexing (QTCREATORBUG-25121)
* Fixed missing completion in `connect` statements (QTCREATORBUG-25153)
### QML
* Fixed reformatter for arrow functions (QTCREATORBUG-23019)
* Fixed reformatter for template strings
### Language Client
* Fixed handling of dynamically registered capabilities
Projects
--------
* Fixed crash in environment settings (QTCREATORBUG-25170)
### qmake
* Fixed unnecessary `qmake` run if `separate_debug_info` is force-disabled
(QTCREATORBUG-25134)
* Fixed wrong messages in `Issues` pane from cumulative parsing
(QTCREATORBUG-25201)
Debugging
---------
### LLDB
* Fixed that application output could be printed delayed (QTCREATORBUG-24667)
### CDB
* Fixed `std::map`, `std::set` and `std::list` pretty printers in release builds
(QTCREATORBUG-24901)
Analyzer
--------
### Clang
* Fixed issue with MSVC and MinGW (QTCREATORBUG-25126)
Platforms
---------
### Remote Linux
* Fixed SSH download operation without session (QTCREATORBUG-25236)
Credits for these changes go to:
--------------------------------
Alessandro Portale
Andre Hartmann
André Pönitz
Björn Schäpers
Christian Kandeler
Christian Stenger
Cristian Adam
David Schulz
Eike Ziller
Henning Gruendl
Ivan Komissarov
Kai Köhne
Kama Wójcik
Knud Dollereder
Leander Schulten
Leena Miettinen
Lukasz Ornatek
Mahmoud Badri
Marco Bubke
Michael Winkelmann
Orgad Shaneh
Thomas Hartmann
Tim Jenssen
Vikas Pachdha

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

View File

@@ -1,6 +1,6 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (C) 2020 The Qt Company Ltd. ** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/ ** Contact: https://www.qt.io/licensing/
** **
** This file is part of the Qt Creator documentation. ** This file is part of the Qt Creator documentation.
@@ -843,6 +843,31 @@
Linux, LLDB on macOS, and CDB on Windows, or any other platform on which at Linux, LLDB on macOS, and CDB on Windows, or any other platform on which at
least one of the three supported backends is available. least one of the three supported backends is available.
\section2 Customizing Built-In Debugging Helpers
You can have commands executed after built-in debugging helpers have
been loaded and fully initialized. To load additional debugging helpers or
modify existing ones, select \uicontrol Tools > \uicontrol Options >
\uicontrol Debugger > \uicontrol {Locals & Expressions}, and enter the
commands in the \uicontrol {Debugging Helper Customization} field.
\image qtcreator-debugging-helper-options.png
If you receive error messages about receiving signals when using GDB, you
can specify \l{https://sourceware.org/gdb/onlinedocs/gdb/Signals.html}
{GDB commands} for handling the signals. For example, you can tell GDB to
ignore the \c SIGSTOP signal if you receive the following error message:
\c {The inferior stopped because it received a signal from the operating
system. Signal name: SIGSTOP}.
To stop GDB from handling the \c SIGSTOP signal, add the following commands
to the \uicontrol {Debugging Helper Customization} field:
\badcode
handle SIGSTOP nopass
handle SIGSTOP nostop
\endcode
\section2 Adding Custom Debugging Helpers \section2 Adding Custom Debugging Helpers
To add debugging helpers for your own types, no compilation is required, To add debugging helpers for your own types, no compilation is required,
@@ -889,9 +914,6 @@
\uicontrol Tools > \uicontrol Options > \uicontrol Debugger > \uicontrol Tools > \uicontrol Options > \uicontrol Debugger >
\uicontrol {Locals & Expressions} > \uicontrol {Locals & Expressions} >
\uicontrol {Extra Debugging Helpers}. \uicontrol {Extra Debugging Helpers}.
\image qtcreator-debugging-helper-options.png
\endlist \endlist
The custom debugging helpers will be automatically picked up from The custom debugging helpers will be automatically picked up from

View File

@@ -1,6 +1,6 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (C) 2020 The Qt Company Ltd. ** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/ ** Contact: https://www.qt.io/licensing/
** **
** This file is part of the Qt Creator documentation. ** This file is part of the Qt Creator documentation.
@@ -218,12 +218,13 @@
when you write code. when you write code.
\if defined(qtcreator) \if defined(qtcreator)
Also specify a text string or C++ or QML code construct Also specify a text string or C++ or QML code construct
in the snippet editor, depending on the snippet category. You can use in the snippet editor, depending on the snippet category.
\l{Using Qt Creator Variables}{predefined variables} in snippets.
\else \else
Also specify a text string or QML code in the snippet editor, depending on Also specify a text string or QML code in the snippet editor, depending on
the snippet category. the snippet category.
\endif \endif
You can use \l{Using Qt Creator Variables}{predefined variables} in
snippets.
The snippet editor provides you with: The snippet editor provides you with:
@@ -319,5 +320,7 @@
To use Nimsuggest, you must install it on the development PC. Then select To use Nimsuggest, you must install it on the development PC. Then select
\uicontrol Tools > \uicontrol Options > \uicontrol Nim > \uicontrol Tools, \uicontrol Tools > \uicontrol Options > \uicontrol Nim > \uicontrol Tools,
and enter the path to the tool executable in the \uicontrol Path field. and enter the path to the tool executable in the \uicontrol Path field.
\else
\include qtcreator-variables.qdocinc qtcreator variables
\endif \endif
*/ */

View File

@@ -1,6 +1,6 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (C) 2020 The Qt Company Ltd. ** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/ ** Contact: https://www.qt.io/licensing/
** **
** This file is part of the Qt Creator documentation. ** This file is part of the Qt Creator documentation.
@@ -93,49 +93,11 @@
\section1 Using Environment Variables \section1 Using Environment Variables
You can use any environment variables to in build, deploy, and run You can use any environment variables in build, deploy, and run
configurations. For a list of variable names, select \uicontrol {Build configurations. For a list of variable names, select \uicontrol {Build
Settings} > \uicontrol {Build Environment} > \uicontrol Details}. Settings} > \uicontrol {Build Environment} > \uicontrol Details.
Environment variables are referenced using the native syntax: $VARNAME Environment variables are referenced using the native syntax: $VARNAME
or ${VARNAME} on Unix and %VARNAME% on Windows. or ${VARNAME} on Unix and %VARNAME% on Windows.
\section1 Using Qt Creator Variables \include qtcreator-variables.qdocinc qtcreator variables
You can use \QC variables in arguments, executable paths, and working
directories. The variables take care of quoting their expansions, so you do
not need to put them in quotes. Select the \inlineimage replace.png
(\uicontrol {Variables}) button in a field to select from a list of
variables that are available in a particular context.
The following syntax enables you to use environment variables as \QC
variables: %{Env:VARNAME}.
\QC uses pattern substitution when expanding variable names. To replace the
first match of \e pattern within \e variable with \e replacement, use:
\badcode
%{variable/pattern/replacement}
\endcode
To replace all matches of \e pattern within \e variable with \e replacement,
use:
\badcode
%{variable//pattern/replacement}
\endcode
The pattern can be a regular expression and the replacement can contain
backreferences. For example, if \c %{variable} is \c my123var, then
\c %{variable/(..)(\d+)/\2\1} is expanded to \c {123myvar}.
Instead of the forward slash, you can also use the pound sign (\c #) as
the substitution character. This can be helpful if the value is supposed
to be a file path, in which case forward slashes might get translated
to backslashes on Windows hosts.
To use the default value if the variable is not set, use:
\badcode
%{variable:-default}
\endcode
*/ */

View File

@@ -0,0 +1,74 @@
/****************************************************************************
**
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Creator documentation.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Free Documentation License Usage
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of
** this file. Please review the following information to ensure
** the GNU Free Documentation License version 1.3 requirements
** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
**
****************************************************************************/
/*!
//! [qtcreator variables]
\section1 Using Qt Creator Variables
You can use \QC variables in arguments, executable paths, and working
directories. The variables take care of quoting their expansions, so you do
not need to put them in quotes.
Select the \inlineimage replace.png
(\uicontrol {Variables}) button in a field to select from a list of
variables that are available in a particular context.
For more information about each variable, move the cursor over it in the
list.
\image qtcreator-variables.png "Qt Creator Variables dialog displaying a tooltip"
The following syntax enables you to use environment variables as \QC
variables: %{Env:VARNAME}.
\QC uses pattern substitution when expanding variable names. To replace the
first match of \e pattern within \e variable with \e replacement, use:
\badcode
%{variable/pattern/replacement}
\endcode
To replace all matches of \e pattern within \e variable with \e replacement,
use:
\badcode
%{variable//pattern/replacement}
\endcode
The pattern can be a regular expression and the replacement can contain
backreferences. For example, if \c %{variable} is \c my123var, then
\c %{variable/(..)(\d+)/\2\1} is expanded to \c {123myvar}.
Instead of the forward slash, you can also use the pound sign (\c #) as
the substitution character. This can be helpful if the value is supposed
to be a file path, in which case forward slashes might get translated
to backslashes on Windows hosts.
To use the default value if the variable is not set, use:
\badcode
%{variable:-default}
\endcode
//! [qtcreator variables]
*/

View File

@@ -51,6 +51,7 @@ excludedirs += ../../qtcreator/examples/accelbubble \
../../qtcreator/src/android \ ../../qtcreator/src/android \
../../qtcreator/src/baremetal \ ../../qtcreator/src/baremetal \
../../qtcreator/src/cmake \ ../../qtcreator/src/cmake \
../../qtcreator/src/conan \
../../qtcreator/src/debugger/creator-only \ ../../qtcreator/src/debugger/creator-only \
../../qtcreator/src/editors/creator-only \ ../../qtcreator/src/editors/creator-only \
../../qtcreator/src/howto/creator-only \ ../../qtcreator/src/howto/creator-only \

View File

@@ -650,10 +650,13 @@ static void setKitEnvironment(Kit *k, const McuTarget *mcuTarget,
processPackage(package); processPackage(package);
processPackage(qtForMCUsSdkPackage); processPackage(qtForMCUsSdkPackage);
// Clang not needed in version 1.7+
if (mcuTarget->qulVersion() < QVersionNumber{1,7}) {
const QString path = QLatin1String(HostOsInfo::isWindowsHost() ? "Path" : "PATH"); const QString path = QLatin1String(HostOsInfo::isWindowsHost() ? "Path" : "PATH");
pathAdditions.append("${" + path + "}"); pathAdditions.append("${" + path + "}");
pathAdditions.append(QDir::toNativeSeparators(Core::ICore::libexecPath() + "/clang/bin")); pathAdditions.append(QDir::toNativeSeparators(Core::ICore::libexecPath() + "/clang/bin"));
changes.append({path, pathAdditions.join(HostOsInfo::pathListSeparator())}); changes.append({path, pathAdditions.join(HostOsInfo::pathListSeparator())});
}
if (kitNeedsQtVersion()) if (kitNeedsQtVersion())
changes.append({QLatin1String("LD_LIBRARY_PATH"), "%{Qt:QT_INSTALL_LIBS}"}); changes.append({QLatin1String("LD_LIBRARY_PATH"), "%{Qt:QT_INSTALL_LIBS}"});

View File

@@ -28,6 +28,7 @@
#include "exportnotification.h" #include "exportnotification.h"
#include "designdocument.h" #include "designdocument.h"
#include "nodemetainfo.h"
#include "qmldesignerplugin.h" #include "qmldesignerplugin.h"
#include "rewriterview.h" #include "rewriterview.h"
#include "qmlitemnode.h" #include "qmlitemnode.h"
@@ -43,6 +44,7 @@
#include <QJsonArray> #include <QJsonArray>
#include <QJsonDocument> #include <QJsonDocument>
#include <QLoggingCategory> #include <QLoggingCategory>
#include <QPlainTextEdit>
#include <QWaitCondition> #include <QWaitCondition>
#include <random> #include <random>
@@ -130,13 +132,27 @@ void AssetExporter::exportQml(const Utils::FilePaths &qmlFiles, const Utils::Fil
m_exportFiles = qmlFiles; m_exportFiles = qmlFiles;
m_totalFileCount = m_exportFiles.count(); m_totalFileCount = m_exportFiles.count();
m_components.clear(); m_components.clear();
m_componentUuidCache.clear();
m_exportPath = exportPath; m_exportPath = exportPath;
m_currentState.change(ParsingState::Parsing); m_currentState.change(ParsingState::Parsing);
triggerLoadNextFile();
if (exportAssets) if (exportAssets)
m_assetDumper = make_unique<AssetDumper>(); m_assetDumper = make_unique<AssetDumper>();
else else
m_assetDumper.reset(); m_assetDumper.reset();
QTimer::singleShot(0, this, &AssetExporter::beginExport);
}
void AssetExporter::beginExport()
{
for (const Utils::FilePath &p : m_exportFiles) {
if (m_cancelled)
break;
preprocessQmlFile(p);
}
if (!m_cancelled)
triggerLoadNextFile();
} }
void AssetExporter::cancel() void AssetExporter::cancel()
@@ -253,6 +269,68 @@ Utils::FilePath AssetExporter::componentExportDir(const Component *component) co
return m_exportPath.pathAppended(component->name()); return m_exportPath.pathAppended(component->name());
} }
void AssetExporter::preprocessQmlFile(const Utils::FilePath &path)
{
// Load the QML file and assign UUIDs to items having none.
// Meanwhile cache the Component UUIDs as well
std::unique_ptr<Model> model(Model::create("Item", 2, 7));
Utils::FileReader reader;
if (!reader.fetch(path.toString())) {
ExportNotification::addError(tr("Cannot preprocess file: %1. Error %2")
.arg(path.toString()).arg(reader.errorString()));
return;
}
QPlainTextEdit textEdit;
textEdit.setPlainText(QString::fromUtf8(reader.data()));
NotIndentingTextEditModifier *modifier = new NotIndentingTextEditModifier(&textEdit);
modifier->setParent(model.get());
RewriterView *rewriterView = new RewriterView(QmlDesigner::RewriterView::Validate, model.get());
rewriterView->setCheckSemanticErrors(false);
rewriterView->setTextModifier(modifier);
model->attachView(rewriterView);
rewriterView->restoreAuxiliaryData();
ModelNode rootNode = rewriterView->rootModelNode();
if (!rootNode.isValid()) {
ExportNotification::addError(tr("Cannot preprocess file: %1").arg(path.toString()));
return;
}
if (assignUuids(rootNode)) {
// Some UUIDs were assigned. Rewrite the file.
rewriterView->writeAuxiliaryData();
const QByteArray data = textEdit.toPlainText().toUtf8();
Utils::FileSaver saver(path.toString(), QIODevice::Text);
saver.write(data);
if (!saver.finalize()) {
ExportNotification::addError(tr("Cannot update %1.\n%2")
.arg(path.toString()).arg(saver.errorString()));
return;
}
}
// Cache component UUID
const QString uuid = rootNode.auxiliaryData(Constants::UuidAuxTag).toString();
m_componentUuidCache[path.toString()] = uuid;
}
bool AssetExporter::assignUuids(const ModelNode &root)
{
// Assign an UUID to the node without one.
// Return true if an assignment takes place.
bool changed = false;
for (const ModelNode &node : root.allSubModelNodesAndThisNode()) {
const QString uuid = node.auxiliaryData(Constants::UuidAuxTag).toString();
if (uuid.isEmpty()) {
// Assign an unique identifier to the node.
QByteArray uuid = generateUuid(node);
node.setAuxiliaryData(Constants::UuidAuxTag, QString::fromLatin1(uuid));
changed = true;
}
}
return changed;
}
QByteArray AssetExporter::generateUuid(const ModelNode &node) QByteArray AssetExporter::generateUuid(const ModelNode &node)
{ {
QByteArray uuid; QByteArray uuid;
@@ -263,6 +341,20 @@ QByteArray AssetExporter::generateUuid(const ModelNode &node)
return uuid; return uuid;
} }
QString AssetExporter::componentUuid(const ModelNode &instance) const
{
// Returns the UUID of the component's root node
// Empty string is returned if the node is not an instance of a component within
// the project.
NodeMetaInfo metaInfo = instance.metaInfo();
if (!metaInfo.isValid())
return {};
const QString path = metaInfo.componentFileName();
if (m_componentUuidCache.contains(path))
return m_componentUuidCache[path];
return {};
}
void AssetExporter::triggerLoadNextFile() void AssetExporter::triggerLoadNextFile()
{ {
QTimer::singleShot(0, this, &AssetExporter::loadNextFile); QTimer::singleShot(0, this, &AssetExporter::loadNextFile);

View File

@@ -76,6 +76,7 @@ public:
const QString &suffix = {}) const; const QString &suffix = {}) const;
void exportAsset(const QPixmap &asset, const Utils::FilePath &path); void exportAsset(const QPixmap &asset, const Utils::FilePath &path);
QByteArray generateUuid(const ModelNode &node); QByteArray generateUuid(const ModelNode &node);
QString componentUuid(const ModelNode &instance) const;
signals: signals:
void stateChanged(ParsingState); void stateChanged(ParsingState);
@@ -93,6 +94,10 @@ private:
void onQmlFileLoaded(); void onQmlFileLoaded();
Utils::FilePath componentExportDir(const Component *component) const; Utils::FilePath componentExportDir(const Component *component) const;
void beginExport();
void preprocessQmlFile(const Utils::FilePath &path);
bool assignUuids(const ModelNode &root);
private: private:
mutable class State { mutable class State {
public: public:
@@ -109,6 +114,7 @@ private:
Utils::FilePath m_exportPath; Utils::FilePath m_exportPath;
bool m_perComponentExport = false; bool m_perComponentExport = false;
std::vector<std::unique_ptr<Component>> m_components; std::vector<std::unique_ptr<Component>> m_components;
QHash<QString, QString> m_componentUuidCache;
QSet<QByteArray> m_usedHashes; QSet<QByteArray> m_usedHashes;
QHash<QString, QPixmap> m_assets; QHash<QString, QPixmap> m_assets;
std::unique_ptr<AssetDumper> m_assetDumper; std::unique_ptr<AssetDumper> m_assetDumper;

View File

@@ -67,7 +67,8 @@ const char ReferenceAssetTag[] = "referenceAsset";
const char AssetPathTag[] = "assetPath"; const char AssetPathTag[] = "assetPath";
const char AssetBoundsTag[] = "assetBounds"; const char AssetBoundsTag[] = "assetBounds";
const char OpacityTag[] = "opacity"; const char OpacityTag[] = "opacity";
const char TypeNameTag[] = "qmlType"; const char TypeNameTag[] = "typeName";
const char TypeIdTag[] = "typeId";
const char TextDetailsTag[] = "textDetails"; const char TextDetailsTag[] = "textDetails";
const char FontFamilyTag[] = "fontFamily"; const char FontFamilyTag[] = "fontFamily";

View File

@@ -130,12 +130,6 @@ QJsonObject Component::nodeToJson(const ModelNode &node)
std::unique_ptr<NodeDumper> dumper(createNodeDumper(node)); std::unique_ptr<NodeDumper> dumper(createNodeDumper(node));
if (dumper) { if (dumper) {
if (dumper->uuid().isEmpty()) {
// Assign an unique identifier to the node.
QByteArray uuid = m_exporter.generateUuid(node);
node.setAuxiliaryData(Constants::UuidAuxTag, QString::fromLatin1(uuid));
node.model()->rewriterView()->writeAuxiliaryData();
}
jsonObject = dumper->json(*this); jsonObject = dumper->json(*this);
} else { } else {
ExportNotification::addError(tr("Error exporting node %1. Cannot parse type %2.") ExportNotification::addError(tr("Error exporting node %1. Cannot parse type %2.")

View File

@@ -25,6 +25,8 @@
#include "itemnodedumper.h" #include "itemnodedumper.h"
#include "assetexportpluginconstants.h" #include "assetexportpluginconstants.h"
#include "assetexporter.h"
#include "componentexporter.h"
#include "qmlitemnode.h" #include "qmlitemnode.h"
@@ -83,6 +85,10 @@ QJsonObject QmlDesigner::ItemNodeDumper::json(QmlDesigner::Component &component)
metadata.insert(ExportTypeTag, ExportTypeChild); metadata.insert(ExportTypeTag, ExportTypeChild);
metadata.insert(TypeNameTag, QString::fromLatin1(m_node.type())); metadata.insert(TypeNameTag, QString::fromLatin1(m_node.type()));
QString typeId = component.exporter().componentUuid(m_node);
if (!typeId.isEmpty())
metadata.insert(TypeIdTag, typeId);
jsonObject.insert(MetadataTag, metadata); jsonObject.insert(MetadataTag, metadata);
return jsonObject; return jsonObject;
} }

View File

@@ -60,6 +60,7 @@ AnnotationCommentTab::AnnotationCommentTab(QWidget *parent)
ui->titleEdit->setModel(new QStringListModel{QStringList{"Description", ui->titleEdit->setModel(new QStringListModel{QStringList{"Description",
"Display Condition", "Display Condition",
"helper lines", "helper lines",
"position marker",
"highlight", "highlight",
"project author", "project author",
"project confirmed", "project confirmed",

View File

@@ -220,8 +220,8 @@ ModelNode TransitionEditorView::addNewTransition()
for (const QmlPropertyChanges & change : state.propertyChanges()) { for (const QmlPropertyChanges & change : state.propertyChanges()) {
QStringList locList; QStringList locList;
const ModelNode target = change.target(); const ModelNode target = change.target();
const QString targetId = target.id();
if (target.isValid() && target.hasMetaInfo()) { if (target.isValid() && target.hasMetaInfo()) {
const QString targetId = target.id();
for (const VariantProperty &property : change.modelNode().variantProperties()) { for (const VariantProperty &property : change.modelNode().variantProperties()) {
TypeName typeName = target.metaInfo().propertyTypeName(property.name()); TypeName typeName = target.metaInfo().propertyTypeName(property.name());