Merge remote-tracking branch 'origin/4.13' into master

Conflicts:
	share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/ListViewSpecifics.qml
	share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/MouseAreaSpecifics.qml
	share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/RowSpecifics.qml
	share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/FlickableSection.qml
	share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/FontSection.qml
	share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/StandardTextSection.qml

Change-Id: Ie5deacd39ae4f3c0966e7cb41a8fd832dcefbb09
This commit is contained in:
Eike Ziller
2020-09-03 11:17:12 +02:00
82 changed files with 4830 additions and 1429 deletions

View File

@@ -42,8 +42,7 @@ bool AndroidServiceData::isValid() const
{
return !m_className.isEmpty()
&& (!m_isRunInExternalProcess || !m_externalProcessName.isEmpty())
&& (!m_isRunInExternalLibrary || !m_externalLibName.isEmpty())
&& (m_isRunInExternalLibrary || !m_serviceArguments.isEmpty());
&& (!m_isRunInExternalLibrary || !m_externalLibName.isEmpty());
}
void AndroidServiceData::setClassName(const QString &className)
@@ -264,8 +263,6 @@ QVariant AndroidServiceWidget::AndroidServiceModel::data(const QModelIndex &inde
return tr("The process name must be set for a service run in an external process");
else if (index.column() == 4 && m_services[index.row()].isRunInExternalLibrary())
return tr("The library name must be set for a service run in an external library");
else if (index.column() == 5 && !m_services[index.row()].isRunInExternalLibrary())
return tr("The service arguments must be set for a service not run in an external library");
} else if (role == Qt::EditRole) {
if (index.column() == 0)
return m_services[index.row()].className();
@@ -287,10 +284,6 @@ QVariant AndroidServiceWidget::AndroidServiceModel::data(const QModelIndex &inde
if (m_services[index.row()].isRunInExternalLibrary()
&& m_services[index.row()].externalLibraryName().isEmpty())
return Utils::Icons::WARNING.icon();
} else if (index.column() == 5) {
if (!m_services[index.row()].isRunInExternalLibrary()
&& m_services[index.row()].serviceArguments().isEmpty())
return Utils::Icons::WARNING.icon();
}
}
return {};

View File

@@ -35,6 +35,7 @@
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/projectmacro.h>
#include <utils/algorithm.h>
#include <utils/cpplanguage_details.h>
#include <utils/fileutils.h>
#include <utils/qtcassert.h>
@@ -137,7 +138,7 @@ QStringList CompilerOptionsBuilder::build(ProjectFile::Kind fileKind,
addTargetTriple();
updateFileLanguage(fileKind);
addLanguageVersionAndExtensions();
enableExceptions();
addMsvcExceptions();
addPrecompiledHeaderOptions(usePrecompiledHeaders);
addProjectConfigFileInclude();
@@ -273,6 +274,17 @@ void CompilerOptionsBuilder::addCompilerFlags()
add(m_compilerFlags.flags);
}
void CompilerOptionsBuilder::addMsvcExceptions()
{
if (!m_clStyle)
return;
if (Utils::anyOf(m_projectPart.toolChainMacros, [](const ProjectExplorer::Macro &macro) {
return macro.key == "_CPPUNWIND";
})) {
enableExceptions();
}
}
void CompilerOptionsBuilder::enableExceptions()
{
// With "--driver-mode=cl" exceptions are disabled (clang 8).

View File

@@ -68,6 +68,7 @@ public:
void addExtraCodeModelFlags();
void addPicIfCompilerFlagsContainsIt();
void addCompilerFlags();
void addMsvcExceptions();
void enableExceptions();
void insertWrappedQtHeaders();
void insertWrappedMingwHeaders();

View File

@@ -26,6 +26,8 @@
#include "componentexporter.h"
#include "exportnotification.h"
#include "designdocument.h"
#include "qmldesignerplugin.h"
#include "rewriterview.h"
#include "qmlitemnode.h"
#include "qmlobjectnode.h"
@@ -163,7 +165,6 @@ void AssetExporter::exportComponent(const ModelNode &rootNode)
Component exporter(*this, rootNode);
exporter.exportComponent();
m_components.append(exporter.json());
notifyProgress((m_totalFileCount - m_exportFiles.count()) * 0.8 / m_totalFileCount);
}
void AssetExporter::notifyLoadError(AssetExporterView::LoadState state)
@@ -192,12 +193,22 @@ void AssetExporter::onQmlFileLoaded()
{
QTC_ASSERT(m_view && m_view->model(), qCDebug(loggerError) << "Null model"; return);
qCDebug(loggerInfo) << "Qml file load done" << m_view->model()->fileUrl();
exportComponent(m_view->rootModelNode());
QString error;
if (!m_view->saveQmlFile(&error)) {
ExportNotification::addError(tr("Error saving QML file. %1")
.arg(error.isEmpty()? tr("Unknown") : error));
QmlDesigner::DesignDocument *designDocument = QmlDesigner::QmlDesignerPlugin::instance()
->documentManager()
.currentDesignDocument();
if (designDocument->hasQmlParseErrors()) {
ExportNotification::addError(tr("Cannot export QML. Document \"%1\" have parsing errors.")
.arg(designDocument->displayName()));
} else {
exportComponent(m_view->rootModelNode());
QString error;
if (!m_view->saveQmlFile(&error)) {
ExportNotification::addError(tr("Error saving QML file. %1")
.arg(error.isEmpty()? tr("Unknown") : error));
}
}
notifyProgress((m_totalFileCount - m_exportFiles.count()) * 0.8 / m_totalFileCount);
triggerLoadNextFile();
}

View File

@@ -30,6 +30,7 @@
#include "model.h"
#include "nodeabstractproperty.h"
#include "nodemetainfo.h"
#include "rewriterview.h"
#include "utils/qtcassert.h"
@@ -41,13 +42,16 @@
namespace {
Q_LOGGING_CATEGORY(loggerInfo, "qtc.designer.assetExportPlugin.modelExporter", QtInfoMsg)
static void populateLineage(const QmlDesigner::ModelNode &node, QByteArrayList &lineage)
static QByteArrayList populateLineage(const QmlDesigner::ModelNode &node)
{
QByteArrayList lineage;
if (!node.isValid() || node.type().isEmpty())
return;
lineage.append(node.type());
if (node.hasParentProperty())
populateLineage(node.parentProperty().parentModelNode(), lineage);
return {};
for (auto &info : node.metaInfo().superClasses())
lineage.append(info.typeName());
return lineage;
}
}
@@ -86,8 +90,7 @@ void Component::exportComponent()
ModelNodeParser *Component::createNodeParser(const ModelNode &node) const
{
QByteArrayList lineage;
populateLineage(node, lineage);
QByteArrayList lineage = populateLineage(node);
std::unique_ptr<ModelNodeParser> reader;
for (auto &parserCreator: m_readers) {
std::unique_ptr<ModelNodeParser> r(parserCreator->instance(lineage, node));
@@ -110,6 +113,11 @@ ModelNodeParser *Component::createNodeParser(const ModelNode &node) const
QJsonObject Component::nodeToJson(const ModelNode &node)
{
QJsonObject jsonObject;
// Don't export States, Connection, Timeline etc nodes.
if (!node.isSubclassOf("QtQuick.Item"))
return {};
std::unique_ptr<ModelNodeParser> parser(createNodeParser(node));
if (parser) {
if (parser->uuid().isEmpty()) {
@@ -120,13 +128,16 @@ QJsonObject Component::nodeToJson(const ModelNode &node)
}
jsonObject = parser->json(*this);
} else {
ExportNotification::addError(tr("Error exporting component %1. Parser unavailable.")
.arg(node.id()));
ExportNotification::addError(tr("Error exporting node %1. Cannot parse type %2.")
.arg(node.id()).arg(QString::fromUtf8(node.type())));
}
QJsonArray children;
for (const ModelNode &childnode : node.directSubModelNodes())
children.append(nodeToJson(childnode));
for (const ModelNode &childnode : node.directSubModelNodes()) {
const QJsonObject childJson = nodeToJson(childnode);
if (!childJson.isEmpty())
children.append(childJson);
}
if (!children.isEmpty())
jsonObject.insert(ChildrenTag, children);

View File

@@ -1297,6 +1297,9 @@ void DesignerActionManager::createDefaultAddResourceHandler()
registerAddResourceHandler(AddResourceHandler(ComponentCoreConstants::addImagesDisplayString,
"*.svg",
ModelNodeOperations::addImageToProject));
registerAddResourceHandler(AddResourceHandler(ComponentCoreConstants::addImagesDisplayString,
"*.hdr",
ModelNodeOperations::addImageToProject));
registerAddResourceHandler(AddResourceHandler(ComponentCoreConstants::addFontsDisplayString,
"*.ttf",

View File

@@ -298,7 +298,7 @@ QWidget *ConnectionDelegate::createEditor(QWidget *parent, const QStyleOptionVie
auto addMetaInfoProperties = [&](const NodeMetaInfo& itemMetaInfo, QString itemName){
if (itemMetaInfo.isValid()) {
for (const PropertyName &propertyName : itemMetaInfo.directPropertyNames()) {
for (const PropertyName &propertyName : itemMetaInfo.propertyNames()) {
TypeName propertyType = itemMetaInfo.propertyTypeName(propertyName);
if (!propertyType.isEmpty()) {
//first letter is a reliable item indicator

View File

@@ -112,7 +112,7 @@ void Edit3DView::updateActiveScene3D(const QVariantMap &sceneState)
if (sceneState.contains(sceneKey)) {
qint32 newActiveScene = sceneState[sceneKey].value<qint32>();
edit3DWidget()->canvas()->updateActiveScene(newActiveScene);
rootModelNode().setAuxiliaryData("active3dScene", newActiveScene);
rootModelNode().setAuxiliaryData("active3dScene@Internal", newActiveScene);
}
if (sceneState.contains(selectKey))

View File

@@ -702,6 +702,8 @@ void FormEditorView::instanceInformationsChanged(const QMultiHash<ModelNode, Inf
}
}
scene()->update();
m_currentTool->formEditorItemsChanged(changedItems);
}

View File

@@ -99,15 +99,15 @@ void ImportsWidget::setPossibleImports(QList<Import> possibleImports)
QList<Import> filteredImports;
const QStringList mcuWhiteList = {"QtQuick", "QtQuick.Controls", "QtQuick.Timeline"};
const QStringList mcuBlackList = {"FlowView"};
const QStringList mcuPostiveList = {"QtQuick", "QtQuick.Controls", "QtQuick.Timeline"};
const QStringList mcuNegativeList = {"FlowView"};
if (isQtForMCUs) {
filteredImports = Utils::filtered(possibleImports,
[mcuWhiteList, mcuBlackList](const Import &import) {
return (mcuWhiteList.contains(import.url())
[mcuPostiveList, mcuNegativeList](const Import &import) {
return (mcuPostiveList.contains(import.url())
|| !import.url().startsWith("Qt"))
&& !mcuBlackList.contains(import.url());
&& !mcuNegativeList.contains(import.url());
});
} else {
filteredImports = possibleImports;

View File

@@ -33,6 +33,9 @@
#include <nodehints.h>
#include <nodemetainfo.h>
#include <designdocument.h>
#include <qmldesignerplugin.h>
#include <utils/algorithm.h>
#include <utils/qtcassert.h>
@@ -197,11 +200,58 @@ void ItemLibraryModel::update(ItemLibraryInfo *itemLibraryInfo, Model *model)
forceVisiblity = isItem;
}
DesignDocument *designDocument = QmlDesignerPlugin::instance()
->documentManager()
.currentDesignDocument();
if (valid
&& (isItem || forceVisiblity) //We can change if the navigator does support pure QObjects
&& (entry.requiredImport().isEmpty()
|| model->hasImport(entryToImport(entry), true, true))) {
if (designDocument && designDocument->isQtForMCUsProject()) {
const QList<TypeName> blockTypes = {"QtQuick.AnimatedImage",
"QtQuick.BorderImage",
"QtQuick.FocusScope",
"QtQuick.TextInput",
"QtQuick.TextEdit",
"QtQuick.Flow",
"QtQuick.Grid",
"QtQuick.GridView",
"QtQuick.PathView",
"QtQuick.Controls",
"QtQuick.Controls.BusyIndicator",
"QtQuick.Controls.ButtonGroup",
"QtQuick.Controls.CheckDelegate",
"QtQuick.Controls.Container",
"QtQuick.Controls.ComboBox",
"QtQuick.Controls.DelayButton",
"QtQuick.Controls.Frame",
"QtQuick.Controls.GroupBox",
"QtQuick.Controls.ItemDelegate",
"QtQuick.Controls.Label",
"QtQuick.Controls.Page",
"QtQuick.Controls.PageIndicator",
"QtQuick.Controls.Pane",
"QtQuick.Controls.RadioDelegate",
"QtQuick.Controls.RangeSlider",
"QtQuick.Controls.RoundButton",
"QtQuick.Controls.ScrollView",
"QtQuick.Controls.SpinBox",
"QtQuick.Controls.StackView",
"QtQuick.Controls.SwipeDelegate",
"QtQuick.Controls.SwitchDelegate",
"QtQuick.Controls.ToolBar",
"QtQuick.Controls.ToolButton",
"QtQuick.Controls.TabBar",
"QtQuick.Controls.TabButton",
"QtQuick.Controls.TextArea",
"QtQuick.Controls.TextField",
"QtQuick.Controls.ToolSeparator",
"QtQuick.Controls.Tumbler"};
if (blockTypes.contains(entry.typeName()))
valid = false;
}
if (valid && (isItem || forceVisiblity) //We can change if the navigator does support pure QObjects
&& (entry.requiredImport().isEmpty()
|| model->hasImport(entryToImport(entry), true, true))) {
QString itemSectionName = entry.category();
qCInfo(itemlibraryPopulate) << "Adding:" << entry.typeName() << "to:" << entry.category();
ItemLibrarySection *sectionModel = sectionByName(itemSectionName);

View File

@@ -351,6 +351,8 @@ void ItemLibraryWidget::reloadQmlSource()
void ItemLibraryWidget::setupImportTagWidget()
{
QTC_ASSERT(m_model, return);
const DesignDocument *designDocument = QmlDesignerPlugin::instance()->currentDesignDocument();
const bool isQtForMCUs = designDocument && designDocument->isQtForMCUsProject();
const QStringList imports = m_model->metaInfo().itemLibraryInfo()->showTagsForImports();
@@ -373,11 +375,13 @@ void ItemLibraryWidget::setupImportTagWidget()
return button;
};
for (const QString &importPath : imports) {
const Import import = Import::createLibraryImport(importPath);
if (!m_model->hasImport(import, true, true)
if (!isQtForMCUs) {
for (const QString &importPath : imports) {
const Import import = Import::createLibraryImport(importPath);
if (!m_model->hasImport(import, true, true)
&& m_model->isImportPossible(import, true, true))
flowLayout->addWidget(createButton(importPath));
flowLayout->addWidget(createButton(importPath));
}
}
}

View File

@@ -272,21 +272,68 @@ static bool itemOrImage(const QmlDesigner::NodeMetaInfo &metaInfo)
return false;
}
static QList<QByteArray> prepareNonMcuProperties()
{
QList<QByteArray> result;
const QList<QByteArray> itemProperties = {"layer", "opacity", "gradient", "smooth", "antialiasing",
"border", "baselineOffset", "focus", "activeFocusOnTab"};
const QList<QByteArray> mouseAreaProperties = {"propagateComposedEvents", "preventStealing", "cursorShape",
"scrollGestureEnabled", "drag", "acceptedButtons", "hoverEnabled"};
const QList<QByteArray> flickableProperties = {"boundsBehavior", "boundsMovement",
"flickDeceleration", "flickableDirection",
"leftMargin", "rightMargin", "bottomMargin", "topMargin",
"originX", "originY",
"pixelAligned", "pressDelay", "synchronousDrag"};
const QList<QByteArray> imageProperties = {"mirror", "mipmap", "cache", "autoTransform", "asynchronous",
"sourceSize", "smooth"};
const QList<QByteArray> textProperties = {"elide", "lineHeight", "lineHeightMode", "wrapMode", "style",
"styleColor", "minimumPointSize", "minimumPixelSize", "styleColor",
"fontSizeMode", "renderType", "textFormat", "maximumLineCount"};
const QList<QByteArray> paddingProperties = {"bottomPadding", "topPadding", "leftPadding", "rightPadding"};
const QList<QByteArray> columnRowProperties = {"layoutDirection"};
const QList<QByteArray> listViewProperties = {"cacheBuffer", "highlightRangeMode", "highlightMoveDuration",
"highlightResizeDuration", "preferredHighlightBegin", "layoutDirection",
"preferredHighlightEnd", "highlightFollowsCurrentItem", "keyNavigationWraps",
"snapMode", "highlightMoveVelocity", "highlightResizeVelocity"};
result.append(itemProperties);
result.append(mouseAreaProperties);
result.append(flickableProperties);
result.append(imageProperties);
result.append(textProperties);
result.append(paddingProperties);
result.append(columnRowProperties);
result.append(listViewProperties);
return result;
}
bool PropertyEditorValue::isAvailable() const
{
const QList<QByteArray> mcuProperties = {"layer", "opacity", "gradient", "smooth", "antialiasing"};
const QList<QByteArray> nonMcuProperties = prepareNonMcuProperties();
const QByteArray fontPrefix = {"font"};
const QList<QByteArray> nonMcuFontProperties = {"wordSpacing", "letterSpacing", "hintingPreference",
"kerning", "preferShaping", "capitalization",
"strikeout", "underline", "styleName"};
const QList<QByteArray> mcuTransformProperties = {"rotation", "scale", "transformOrigin"};
const QList<QByteArray> list = name().split('.');
const QByteArray pureName = list.first();
const QByteArray pureName = list.constFirst();
QmlDesigner::DesignDocument *designDocument = QmlDesigner::QmlDesignerPlugin::instance()
->documentManager()
.currentDesignDocument();
if (designDocument && designDocument->isQtForMCUsProject()) {
if (mcuProperties.contains(pureName))
if (pureName == fontPrefix) {
if (nonMcuFontProperties.contains(list.constLast()))
return false;
}
if (nonMcuProperties.contains(pureName))
return false;
if (mcuTransformProperties.contains(pureName) && !itemOrImage(m_modelNode.metaInfo()))
return false;

View File

@@ -207,20 +207,20 @@ void SplineEditor::contextMenuEvent(QContextMenuEvent *e)
{
m_curve.clearActive();
QMenu menu;
auto *menu = new QMenu(this);
EasingCurve mappedCurve = m_canvas.mapTo(m_curve);
int index = mappedCurve.hit(e->pos(), 10);
if (index > 0 && !m_curve.isHandle(index)) {
QAction *deleteAction = menu.addAction(tr("Delete Point"));
QAction *deleteAction = menu->addAction(tr("Delete Point"));
connect(deleteAction, &QAction::triggered, [this, index]() {
m_curve.deletePoint(index);
update();
emit easingCurveChanged(m_curve);
});
QAction *smoothAction = menu.addAction(tr("Smooth Point"));
QAction *smoothAction = menu->addAction(tr("Smooth Point"));
smoothAction->setCheckable(true);
smoothAction->setChecked(m_curve.isSmooth(index));
connect(smoothAction, &QAction::triggered, [this, index]() {
@@ -229,7 +229,7 @@ void SplineEditor::contextMenuEvent(QContextMenuEvent *e)
emit easingCurveChanged(m_curve);
});
QAction *cornerAction = menu.addAction(tr("Corner Point"));
QAction *cornerAction = menu->addAction(tr("Corner Point"));
connect(cornerAction, &QAction::triggered, [this, index]() {
m_curve.breakTangent(index);
update();
@@ -237,7 +237,7 @@ void SplineEditor::contextMenuEvent(QContextMenuEvent *e)
});
} else {
QAction *addAction = menu.addAction(tr("Add Point"));
QAction *addAction = menu->addAction(tr("Add Point"));
connect(addAction, &QAction::triggered, [&]() {
m_curve.addPoint(m_canvas.mapFrom(e->pos()));
m_curve.makeSmooth(m_curve.active());
@@ -246,13 +246,13 @@ void SplineEditor::contextMenuEvent(QContextMenuEvent *e)
});
}
QAction *zoomAction = menu.addAction(tr("Reset Zoom"));
QAction *zoomAction = menu->addAction(tr("Reset Zoom"));
connect(zoomAction, &QAction::triggered, [&]() {
m_canvas.setScale(1.0);
update();
});
menu.exec(e->globalPos());
menu->exec(e->globalPos());
e->accept();
}

View File

@@ -548,7 +548,6 @@ QString RewriterView::auxiliaryDataAsQML() const
for (const auto &node : allModelNodes()) {
QHash<PropertyName, QVariant> data = node.auxiliaryData();
if (!data.isEmpty()) {
hasAuxData = true;
if (columnCount > 80) {
str += "\n";
columnCount = 0;
@@ -567,7 +566,6 @@ QString RewriterView::auxiliaryDataAsQML() const
keys.sort();
for (const QString &key : keys) {
if (key.endsWith("@NodeInstance"))
continue;
@@ -579,7 +577,7 @@ QString RewriterView::auxiliaryDataAsQML() const
if (!key.contains(safeName))
continue;
hasAuxData = true;
const QVariant value = data.value(key.toUtf8());
QString strValue = value.toString();

View File

@@ -35,7 +35,7 @@ ListModel {
ListElement {
projectName: "CoffeeMachine"
qmlFileName: "ApplicationFlowForm.ui.qml"
qmlFileName: "CoffeeMachine.qml"
thumbnail: "images/coffeemachinedemo_thumbnail.png"
displayName: "Coffee Machine"
}

View File

@@ -91,4 +91,46 @@ ListModel {
thumbnail: "images/what_is_new_15.png"
url: "https://www.youtube.com/watch?v=e-HAZrisi5o"
}
ListElement {
displayName: "Qt Design Studio QuickTip: UI Navigation"
thumbnail: "images/Qt_QT_nav.png"
url: "https://youtu.be/RfEYO-5Mw6s"
}
ListElement {
displayName: "Qt Design Studio QuickTip: Text Element"
thumbnail: "images/Qt_QT_textElement.png"
url: "https://youtu.be/yOUdg1o2KJM"
}
ListElement {
displayName: "Qt Design Studio QuickTip: Animated Image"
thumbnail: "images/Qt_QT_animatedImage.png"
url: "https://youtu.be/DVWd_xMMgvg"
}
ListElement {
displayName: "Qt Design Studio QuickTip: Slider Control"
thumbnail: "images/Qt_QT_sliderControl.png"
url: "https://youtu.be/Ed8WS03C-Vk"
}
ListElement {
displayName: "Qt Design Studio QuickTip: Bindings"
thumbnail: "images/Qt_QT_bindings.png"
url: "https://youtu.be/UfvA04CIXv0"
}
ListElement {
displayName: "Sketch Bridge Tutorial - Part 1"
thumbnail: "images/sketchTutorial_1.png"
url: "https://www.qt.io/blog/qt-design-studio-sketch-bridge-tutorial-part-1"
}
ListElement {
displayName: "Sketch Bridge Tutorial - Part 2"
thumbnail: "images/sketchTutorial_2.png"
url: "https://www.qt.io/blog/qt-design-studio-sketch-bridge-tutorial-part-2"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 54 KiB