forked from qt-creator/qt-creator
Add stylesheet merger
Adds classes to merge a template qml file and a qml stylesheet that have been exported from other design tools into a resulting qml file that can be used for further processing in Qt Design Studio. Current issues: * Sometimes it makes sense to define width and height if an anchor is present, but most of the time not. * Actually if the hierachy was defined (e.g. Text item not child of background) most likely the anchors should be ignored. But this would be just a "dirty" heuristic. I suggest to let the template decide. If the template has anchors those have "precedence". It is always possible to define templates without anchors. Task-number: QDS-2071 Change-Id: I9159514a8e884b7ffc31897aef4551b5efbbcb87 Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
committed by
Thomas Hartmann
parent
5b00401850
commit
de8eb93637
@@ -457,6 +457,7 @@ extend_qtc_plugin(QmlDesigner
|
|||||||
include/rewriterview.h
|
include/rewriterview.h
|
||||||
include/rewritingexception.h
|
include/rewritingexception.h
|
||||||
include/signalhandlerproperty.h
|
include/signalhandlerproperty.h
|
||||||
|
include/stylesheetmerger.h
|
||||||
include/subcomponentmanager.h
|
include/subcomponentmanager.h
|
||||||
include/textmodifier.h
|
include/textmodifier.h
|
||||||
include/variantproperty.h
|
include/variantproperty.h
|
||||||
@@ -530,6 +531,7 @@ extend_qtc_plugin(QmlDesigner
|
|||||||
model/rewriteactioncompressor.cpp model/rewriteactioncompressor.h
|
model/rewriteactioncompressor.cpp model/rewriteactioncompressor.h
|
||||||
model/rewriterview.cpp
|
model/rewriterview.cpp
|
||||||
model/signalhandlerproperty.cpp
|
model/signalhandlerproperty.cpp
|
||||||
|
model/stylesheetmerger.cpp
|
||||||
model/textmodifier.cpp
|
model/textmodifier.cpp
|
||||||
model/texttomodelmerger.cpp model/texttomodelmerger.h
|
model/texttomodelmerger.cpp model/texttomodelmerger.h
|
||||||
model/variantproperty.cpp
|
model/variantproperty.cpp
|
||||||
|
@@ -83,7 +83,8 @@ SOURCES += $$PWD/model/abstractview.cpp \
|
|||||||
$$PWD/instances/puppetdialog.cpp \
|
$$PWD/instances/puppetdialog.cpp \
|
||||||
$$PWD/model/qmltimeline.cpp \
|
$$PWD/model/qmltimeline.cpp \
|
||||||
$$PWD/model/qmltimelinekeyframegroup.cpp \
|
$$PWD/model/qmltimelinekeyframegroup.cpp \
|
||||||
$$PWD/model/annotation.cpp
|
$$PWD/model/annotation.cpp \
|
||||||
|
$$PWD/model/stylesheetmerger.cpp
|
||||||
|
|
||||||
HEADERS += $$PWD/include/qmldesignercorelib_global.h \
|
HEADERS += $$PWD/include/qmldesignercorelib_global.h \
|
||||||
$$PWD/include/abstractview.h \
|
$$PWD/include/abstractview.h \
|
||||||
@@ -160,7 +161,8 @@ HEADERS += $$PWD/include/qmldesignercorelib_global.h \
|
|||||||
$$PWD/instances/puppetdialog.h \
|
$$PWD/instances/puppetdialog.h \
|
||||||
$$PWD/include/qmltimeline.h \
|
$$PWD/include/qmltimeline.h \
|
||||||
$$PWD/include/qmltimelinekeyframegroup.h \
|
$$PWD/include/qmltimelinekeyframegroup.h \
|
||||||
$$PWD/include/annotation.h
|
$$PWD/include/annotation.h \
|
||||||
|
$$PWD/include/stylesheetmerger.h
|
||||||
|
|
||||||
FORMS += \
|
FORMS += \
|
||||||
$$PWD/instances/puppetdialog.ui
|
$$PWD/instances/puppetdialog.ui
|
||||||
|
@@ -0,0 +1,71 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2020 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
#ifndef STYLESHEETMERGER_H
|
||||||
|
#define STYLESHEETMERGER_H
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
#include <QHash>
|
||||||
|
#include <modelnode.h>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class AbstractView;
|
||||||
|
|
||||||
|
struct ReparentInfo {
|
||||||
|
QString generatedId;
|
||||||
|
QString templateId;
|
||||||
|
QString templateParentId;
|
||||||
|
int parentIndex;
|
||||||
|
bool alreadyReparented;
|
||||||
|
};
|
||||||
|
|
||||||
|
class StylesheetMerger {
|
||||||
|
public:
|
||||||
|
StylesheetMerger(AbstractView*, AbstractView*);
|
||||||
|
void merge();
|
||||||
|
private:
|
||||||
|
void preprocessStyleSheet();
|
||||||
|
bool idExistsInBothModels(const QString& id);
|
||||||
|
void replaceNode(ModelNode&, ModelNode&);
|
||||||
|
void replaceRootNode(ModelNode& templateRootNode);
|
||||||
|
void applyStyleProperties(ModelNode &templateNode, const ModelNode &styleNode);
|
||||||
|
void adjustNodeIndex(ModelNode &node);
|
||||||
|
void setupIdRenamingHash();
|
||||||
|
ModelNode createReplacementNode(const ModelNode &styleNode, ModelNode &modelNode);
|
||||||
|
void syncNodeProperties(ModelNode &outputNode, const ModelNode &inputNode, bool skipDuplicates = false);
|
||||||
|
void syncNodeListProperties(ModelNode &outputNode, const ModelNode &inputNode, bool skipDuplicates = false);
|
||||||
|
void syncId(ModelNode &outputNode, ModelNode &inputNode);
|
||||||
|
void syncBindingProperties(ModelNode &outputNode, const ModelNode &inputNode);
|
||||||
|
void syncAuxiliaryProperties(ModelNode &outputNode, const ModelNode &inputNode);
|
||||||
|
void syncVariantProperties(ModelNode &outputNode, const ModelNode &inputNode);
|
||||||
|
|
||||||
|
AbstractView *m_templateView;
|
||||||
|
AbstractView *m_styleView;
|
||||||
|
QHash<QString, ReparentInfo> m_reparentInfoHash;
|
||||||
|
QHash<QString, QString> m_idReplacementHash;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif // STYLESHEETMERGER_H
|
404
src/plugins/qmldesigner/designercore/model/stylesheetmerger.cpp
Normal file
404
src/plugins/qmldesigner/designercore/model/stylesheetmerger.cpp
Normal file
@@ -0,0 +1,404 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2020 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
#include "stylesheetmerger.h"
|
||||||
|
|
||||||
|
#include <abstractview.h>
|
||||||
|
#include <bindingproperty.h>
|
||||||
|
#include <modelmerger.h>
|
||||||
|
#include <nodeabstractproperty.h>
|
||||||
|
#include <nodelistproperty.h>
|
||||||
|
#include <nodemetainfo.h>
|
||||||
|
#include <nodeproperty.h>
|
||||||
|
#include <variantproperty.h>
|
||||||
|
|
||||||
|
#include <QQueue>
|
||||||
|
#include <QRegularExpression>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
static void splitIdInBaseNameAndNumber(const QString &id, QString *baseId, int *number)
|
||||||
|
{
|
||||||
|
|
||||||
|
int counter = 0;
|
||||||
|
while (counter < id.count()) {
|
||||||
|
bool canConvertToInteger = false;
|
||||||
|
int newNumber = id.rightRef(counter +1).toInt(&canConvertToInteger);
|
||||||
|
if (canConvertToInteger)
|
||||||
|
*number = newNumber;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
*baseId = id.left(id.count() - counter);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StylesheetMerger::syncNodeProperties(ModelNode &outputNode, const ModelNode &inputNode, bool skipDuplicates)
|
||||||
|
{
|
||||||
|
foreach (const NodeProperty &nodeProperty, inputNode.nodeProperties()) {
|
||||||
|
ModelNode oldNode = nodeProperty.modelNode();
|
||||||
|
if (m_templateView->hasId(oldNode.id()) && skipDuplicates)
|
||||||
|
continue;
|
||||||
|
ModelNode newNode = createReplacementNode(oldNode, oldNode);
|
||||||
|
// cache the property name as removing it will invalidate it
|
||||||
|
PropertyName propertyName = nodeProperty.name();
|
||||||
|
// remove property first to prevent invalid reparenting situation
|
||||||
|
outputNode.removeProperty(propertyName);
|
||||||
|
outputNode.nodeProperty(propertyName).reparentHere(newNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StylesheetMerger::syncNodeListProperties(ModelNode &outputNode, const ModelNode &inputNode, bool skipDuplicates)
|
||||||
|
{
|
||||||
|
foreach (const NodeListProperty &nodeListProperty, inputNode.nodeListProperties()) {
|
||||||
|
foreach (ModelNode node, nodeListProperty.toModelNodeList()) {
|
||||||
|
if (m_templateView->hasId(node.id()) && skipDuplicates)
|
||||||
|
continue;
|
||||||
|
ModelNode newNode = createReplacementNode(node, node);
|
||||||
|
outputNode.nodeListProperty(nodeListProperty.name()).reparentHere(newNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StylesheetMerger::syncVariantProperties(ModelNode &outputNode, const ModelNode &inputNode)
|
||||||
|
{
|
||||||
|
foreach (const VariantProperty &variantProperty, inputNode.variantProperties()) {
|
||||||
|
outputNode.variantProperty(variantProperty.name()).setValue(variantProperty.value());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StylesheetMerger::syncAuxiliaryProperties(ModelNode &outputNode, const ModelNode &inputNode)
|
||||||
|
{
|
||||||
|
auto tmp = inputNode.auxiliaryData();
|
||||||
|
for (auto iter = tmp.begin(); iter != tmp.end(); ++iter)
|
||||||
|
outputNode.setAuxiliaryData(iter.key(), iter.value());
|
||||||
|
}
|
||||||
|
|
||||||
|
void StylesheetMerger::syncBindingProperties(ModelNode &outputNode, const ModelNode &inputNode)
|
||||||
|
{
|
||||||
|
foreach (const BindingProperty &bindingProperty, inputNode.bindingProperties()) {
|
||||||
|
outputNode.bindingProperty(bindingProperty.name()).setExpression(bindingProperty.expression());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StylesheetMerger::syncId(ModelNode &outputNode, ModelNode &inputNode)
|
||||||
|
{
|
||||||
|
if (!inputNode.id().isEmpty()) {
|
||||||
|
QString id = inputNode.id();
|
||||||
|
QString renamedId = m_idReplacementHash.value(inputNode.id());
|
||||||
|
inputNode.setIdWithoutRefactoring(renamedId);
|
||||||
|
outputNode.setIdWithoutRefactoring(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StylesheetMerger::setupIdRenamingHash()
|
||||||
|
{
|
||||||
|
foreach (const ModelNode &node, m_templateView->rootModelNode().allSubModelNodesAndThisNode()) {
|
||||||
|
if (!node.id().isEmpty()) {
|
||||||
|
QString newId = node.id();
|
||||||
|
QString baseId;
|
||||||
|
int number = 1;
|
||||||
|
splitIdInBaseNameAndNumber(newId, &baseId, &number);
|
||||||
|
|
||||||
|
while (m_templateView->hasId(newId) || m_idReplacementHash.values().contains(newId)) {
|
||||||
|
newId = "stylesheet_auto_merge_" + baseId + QString::number(number);
|
||||||
|
number++;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_idReplacementHash.insert(node.id(), newId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ModelNode StylesheetMerger::createReplacementNode(const ModelNode& styleNode, ModelNode &modelNode)
|
||||||
|
{
|
||||||
|
QList<QPair<PropertyName, QVariant> > propertyList;
|
||||||
|
QList<QPair<PropertyName, QVariant> > variantPropertyList;
|
||||||
|
foreach (const VariantProperty &variantProperty, modelNode.variantProperties()) {
|
||||||
|
propertyList.append(QPair<PropertyName, QVariant>(variantProperty.name(), variantProperty.value()));
|
||||||
|
}
|
||||||
|
NodeMetaInfo nodeMetaInfo = m_templateView->model()->metaInfo(styleNode.type());
|
||||||
|
ModelNode newNode(m_templateView->createModelNode(styleNode.type(), nodeMetaInfo.majorVersion(), nodeMetaInfo.minorVersion(),
|
||||||
|
propertyList, variantPropertyList, styleNode.nodeSource(), styleNode.nodeSourceType()));
|
||||||
|
|
||||||
|
syncAuxiliaryProperties(newNode, modelNode);
|
||||||
|
syncBindingProperties(newNode, modelNode);
|
||||||
|
syncId(newNode, modelNode);
|
||||||
|
syncNodeProperties(newNode, modelNode);
|
||||||
|
syncNodeListProperties(newNode, modelNode);
|
||||||
|
|
||||||
|
return newNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
StylesheetMerger::StylesheetMerger(AbstractView *templateView, AbstractView *styleView)
|
||||||
|
: m_templateView(templateView)
|
||||||
|
, m_styleView(styleView)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StylesheetMerger::idExistsInBothModels(const QString& id)
|
||||||
|
{
|
||||||
|
return m_templateView->hasId(id) && m_styleView->hasId(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
QPoint pointForModelNode(const ModelNode &node)
|
||||||
|
{
|
||||||
|
int x = 0;
|
||||||
|
if (node.hasVariantProperty("x"))
|
||||||
|
x = node.variantProperty("x").value().toInt();
|
||||||
|
|
||||||
|
int y = 0;
|
||||||
|
if (node.hasVariantProperty("y"))
|
||||||
|
y = node.variantProperty("y").value().toInt();
|
||||||
|
|
||||||
|
return QPoint(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
QPoint parentPosition(const ModelNode &node)
|
||||||
|
{
|
||||||
|
QPoint p;
|
||||||
|
|
||||||
|
ModelNode currentNode = node;
|
||||||
|
while (currentNode.hasParentProperty()) {
|
||||||
|
currentNode = currentNode.parentProperty().parentModelNode();
|
||||||
|
p += pointForModelNode(currentNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StylesheetMerger::preprocessStyleSheet()
|
||||||
|
{
|
||||||
|
for (ModelNode currentStyleNode : m_styleView->rootModelNode().directSubModelNodes()) {
|
||||||
|
QString id = currentStyleNode.id();
|
||||||
|
|
||||||
|
if (!idExistsInBothModels(id))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ModelNode templateNode = m_templateView->modelNodeForId(id);
|
||||||
|
NodeAbstractProperty templateParentProperty = templateNode.parentProperty();
|
||||||
|
if (!templateNode.hasParentProperty()
|
||||||
|
|| templateParentProperty.parentModelNode().isRootNode())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ModelNode templateParentNode = templateParentProperty.parentModelNode();
|
||||||
|
const QString parentId = templateParentNode.id();
|
||||||
|
if (!idExistsInBothModels(parentId))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Only get the position properties as the node should have a global
|
||||||
|
// position in the style sheet.
|
||||||
|
const QPoint oldGlobalPos = pointForModelNode(currentStyleNode);
|
||||||
|
|
||||||
|
ModelNode newStyleParent = m_styleView->modelNodeForId(parentId);
|
||||||
|
NodeListProperty newParentProperty = newStyleParent.defaultNodeListProperty();
|
||||||
|
newParentProperty.reparentHere(currentStyleNode);
|
||||||
|
|
||||||
|
// Get the parent position in global coordinates.
|
||||||
|
QPoint parentGlobalPos = parentPosition(currentStyleNode);
|
||||||
|
|
||||||
|
const QPoint newGlobalPos = oldGlobalPos - parentGlobalPos;
|
||||||
|
|
||||||
|
currentStyleNode.variantProperty("x").setValue(newGlobalPos.x());
|
||||||
|
currentStyleNode.variantProperty("y").setValue(newGlobalPos.y());
|
||||||
|
|
||||||
|
int templateParentIndex = templateParentProperty.isNodeListProperty()
|
||||||
|
? templateParentProperty.indexOf(templateNode) : -1;
|
||||||
|
int styleParentIndex = newParentProperty.indexOf(currentStyleNode);
|
||||||
|
if (templateParentIndex >= 0 && styleParentIndex != templateParentIndex)
|
||||||
|
newParentProperty.slide(styleParentIndex, templateParentIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StylesheetMerger::replaceNode(ModelNode &replacedNode, ModelNode &newNode)
|
||||||
|
{
|
||||||
|
NodeListProperty replacedNodeParent;
|
||||||
|
ModelNode parentModelNode = replacedNode.parentProperty().parentModelNode();
|
||||||
|
if (replacedNode.parentProperty().isNodeListProperty())
|
||||||
|
replacedNodeParent = replacedNode.parentProperty().toNodeListProperty();
|
||||||
|
bool isNodeProperty = false;
|
||||||
|
|
||||||
|
PropertyName reparentName;
|
||||||
|
for (NodeProperty prop : parentModelNode.nodeProperties()) {
|
||||||
|
if (prop.modelNode().id() == replacedNode.id()) {
|
||||||
|
isNodeProperty = true;
|
||||||
|
reparentName = prop.name();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ReparentInfo info;
|
||||||
|
info.parentIndex = replacedNodeParent.isValid() ? replacedNodeParent.indexOf(replacedNode) : -1;
|
||||||
|
info.templateId = replacedNode.id();
|
||||||
|
info.templateParentId = parentModelNode.id();
|
||||||
|
info.generatedId = newNode.id();
|
||||||
|
|
||||||
|
if (!isNodeProperty) {
|
||||||
|
replacedNodeParent.reparentHere(newNode);
|
||||||
|
replacedNode.destroy();
|
||||||
|
info.alreadyReparented = true;
|
||||||
|
} else {
|
||||||
|
parentModelNode.removeProperty(reparentName);
|
||||||
|
parentModelNode.nodeProperty(reparentName).reparentHere(newNode);
|
||||||
|
}
|
||||||
|
m_reparentInfoHash.insert(newNode.id(), info);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StylesheetMerger::replaceRootNode(ModelNode& templateRootNode)
|
||||||
|
{
|
||||||
|
ModelMerger merger(m_templateView);
|
||||||
|
QString rootId = templateRootNode.id();
|
||||||
|
// If we shall replace the root node of the template with the style,
|
||||||
|
// we first replace the whole model.
|
||||||
|
ModelNode rootReplacer = m_styleView->modelNodeForId(rootId);
|
||||||
|
merger.replaceModel(rootReplacer);
|
||||||
|
|
||||||
|
// Then reset the id to the old root's one.
|
||||||
|
ModelNode newRoot = m_templateView->rootModelNode();
|
||||||
|
newRoot.setIdWithoutRefactoring(rootId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move the newly created nodes to the correct position in the parent node
|
||||||
|
void StylesheetMerger::adjustNodeIndex(ModelNode &node)
|
||||||
|
{
|
||||||
|
if (!m_reparentInfoHash.contains(node.id()))
|
||||||
|
return;
|
||||||
|
|
||||||
|
ReparentInfo info = m_reparentInfoHash.value(node.id());
|
||||||
|
if (info.parentIndex < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!node.parentProperty().isNodeListProperty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
NodeListProperty parentListProperty = node.parentProperty().toNodeListProperty();
|
||||||
|
int currentIndex = parentListProperty.indexOf(node);
|
||||||
|
if (currentIndex == info.parentIndex)
|
||||||
|
return;
|
||||||
|
|
||||||
|
parentListProperty.slide(currentIndex, info.parentIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StylesheetMerger::applyStyleProperties(ModelNode &templateNode, const ModelNode &styleNode)
|
||||||
|
{
|
||||||
|
QRegExp regEx("[a-z]", Qt::CaseInsensitive);
|
||||||
|
foreach (const VariantProperty &variantProperty, styleNode.variantProperties()) {
|
||||||
|
// check for existing bindings with that property name
|
||||||
|
if (templateNode.hasBindingProperty(variantProperty.name())) {
|
||||||
|
// if the binding does not contain any alpha letters (i.e. binds to a term rather than a property,
|
||||||
|
// replace it with the corresponding variant property.
|
||||||
|
if (!templateNode.bindingProperty(variantProperty.name()).expression().contains(regEx)) {
|
||||||
|
templateNode.removeProperty(variantProperty.name());
|
||||||
|
templateNode.variantProperty(variantProperty.name()).setValue(variantProperty.value());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
templateNode.variantProperty(variantProperty.name()).setValue(variantProperty.value());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
syncBindingProperties(templateNode, styleNode);
|
||||||
|
syncNodeProperties(templateNode, styleNode, true);
|
||||||
|
syncNodeListProperties(templateNode, styleNode, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void removePropertyIfExists(ModelNode node, const PropertyName &propertyName)
|
||||||
|
{
|
||||||
|
if (node.hasProperty(propertyName))
|
||||||
|
node.removeProperty(propertyName);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void StylesheetMerger::merge()
|
||||||
|
{
|
||||||
|
ModelNode templateRootNode = m_templateView->rootModelNode();
|
||||||
|
ModelNode styleRootNode = m_styleView->rootModelNode();
|
||||||
|
|
||||||
|
// first, build up the hierarchy in the style sheet as we have it in the template
|
||||||
|
preprocessStyleSheet();
|
||||||
|
|
||||||
|
// build a hash of generated replacement ids
|
||||||
|
setupIdRenamingHash();
|
||||||
|
|
||||||
|
//in case we are replacing the root node, just do that and exit
|
||||||
|
if (m_styleView->hasId(templateRootNode.id())) {
|
||||||
|
replaceRootNode(templateRootNode);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QQueue<ModelNode> replacementNodes;
|
||||||
|
|
||||||
|
QList<ModelNode> directRootSubNodes = styleRootNode.directSubModelNodes();
|
||||||
|
if (directRootSubNodes.length() == 0 && m_templateView->hasId(styleRootNode.id())) {
|
||||||
|
// if the style sheet has only one node, just replace that one
|
||||||
|
replacementNodes.enqueue(styleRootNode);
|
||||||
|
}
|
||||||
|
// otherwise, the nodes to replace are the direct sub nodes of the style sheet's root
|
||||||
|
for (ModelNode subNode : styleRootNode.allSubModelNodes()) {
|
||||||
|
if (m_templateView->hasId(subNode.id())) {
|
||||||
|
replacementNodes.enqueue(subNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ModelNode currentNode : replacementNodes) {
|
||||||
|
|
||||||
|
bool hasPos = false;
|
||||||
|
|
||||||
|
// create the replacement nodes for the styled nodes
|
||||||
|
{
|
||||||
|
RewriterTransaction transaction(m_templateView, "create-replacement-node");
|
||||||
|
|
||||||
|
ModelNode replacedNode = m_templateView->modelNodeForId(currentNode.id());
|
||||||
|
hasPos = replacedNode.hasProperty("x") || replacedNode.hasProperty("y");
|
||||||
|
|
||||||
|
ModelNode replacementNode = createReplacementNode(currentNode, replacedNode);
|
||||||
|
|
||||||
|
replaceNode(replacedNode, replacementNode);
|
||||||
|
transaction.commit();
|
||||||
|
}
|
||||||
|
// sync the properties from the stylesheet
|
||||||
|
{
|
||||||
|
RewriterTransaction transaction(m_templateView, "sync-style-node-properties");
|
||||||
|
ModelNode templateNode = m_templateView->modelNodeForId(currentNode.id());
|
||||||
|
applyStyleProperties(templateNode, currentNode);
|
||||||
|
adjustNodeIndex(templateNode);
|
||||||
|
|
||||||
|
/* This we want to do if the parent node in the style is not in the template */
|
||||||
|
if (!currentNode.hasParentProperty() ||
|
||||||
|
!m_templateView->modelNodeForId(currentNode.parentProperty().parentModelNode().id()).isValid()) {
|
||||||
|
|
||||||
|
if (!hasPos) { //If template had postition retain it
|
||||||
|
removePropertyIfExists(templateNode, "x");
|
||||||
|
removePropertyIfExists(templateNode, "y");
|
||||||
|
}
|
||||||
|
if (templateNode.hasProperty("anchors.fill")) {
|
||||||
|
/* Unfortuntly there are cases were width and height have to be defined - see Button
|
||||||
|
* Most likely we need options for this */
|
||||||
|
//removePropertyIfExists(templateNode, "width");
|
||||||
|
//removePropertyIfExists(templateNode, "height");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -297,6 +297,7 @@ Project {
|
|||||||
"include/rewriterview.h",
|
"include/rewriterview.h",
|
||||||
"include/rewritingexception.h",
|
"include/rewritingexception.h",
|
||||||
"include/signalhandlerproperty.h",
|
"include/signalhandlerproperty.h",
|
||||||
|
"include/stylesheetmerger.h",
|
||||||
"include/viewmanager.h",
|
"include/viewmanager.h",
|
||||||
"include/subcomponentmanager.h",
|
"include/subcomponentmanager.h",
|
||||||
"include/textmodifier.h",
|
"include/textmodifier.h",
|
||||||
@@ -378,6 +379,7 @@ Project {
|
|||||||
"model/documentmessage.cpp",
|
"model/documentmessage.cpp",
|
||||||
"model/rewriterview.cpp",
|
"model/rewriterview.cpp",
|
||||||
"model/signalhandlerproperty.cpp",
|
"model/signalhandlerproperty.cpp",
|
||||||
|
"model/stylesheetmerger.cpp",
|
||||||
"model/textmodifier.cpp",
|
"model/textmodifier.cpp",
|
||||||
"model/texttomodelmerger.cpp",
|
"model/texttomodelmerger.cpp",
|
||||||
"model/texttomodelmerger.h",
|
"model/texttomodelmerger.h",
|
||||||
|
@@ -61,8 +61,10 @@ SOURCES += \
|
|||||||
../testview.cpp \
|
../testview.cpp \
|
||||||
testrewriterview.cpp \
|
testrewriterview.cpp \
|
||||||
tst_testcore.cpp
|
tst_testcore.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
../testview.h \
|
../testview.h \
|
||||||
testrewriterview.h \
|
testrewriterview.h \
|
||||||
tst_testcore.h
|
tst_testcore.h
|
||||||
|
|
||||||
RESOURCES += ../data/testfiles.qrc
|
RESOURCES += ../data/testfiles.qrc
|
||||||
|
@@ -28,6 +28,7 @@
|
|||||||
#include <QScopedPointer>
|
#include <QScopedPointer>
|
||||||
#include <QLatin1String>
|
#include <QLatin1String>
|
||||||
#include <QGraphicsObject>
|
#include <QGraphicsObject>
|
||||||
|
#include <QQueue>
|
||||||
#include <QTest>
|
#include <QTest>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
|
|
||||||
@@ -42,6 +43,7 @@
|
|||||||
#include <nodeinstanceview.h>
|
#include <nodeinstanceview.h>
|
||||||
#include <nodeinstance.h>
|
#include <nodeinstance.h>
|
||||||
#include <subcomponentmanager.h>
|
#include <subcomponentmanager.h>
|
||||||
|
#include <stylesheetmerger.h>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
#include "../testview.h"
|
#include "../testview.h"
|
||||||
@@ -3704,6 +3706,131 @@ void tst_TestCore::testCopyModelRewriter1()
|
|||||||
QCOMPARE(textEdit1.toPlainText(), expected);
|
QCOMPARE(textEdit1.toPlainText(), expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void adjustPreservedProperties(const ModelNode& replacedNode, ModelNode& newNode) {
|
||||||
|
QSet<PropertyName> preservedProperties;
|
||||||
|
preservedProperties.insert("x");
|
||||||
|
preservedProperties.insert("y");
|
||||||
|
preservedProperties.insert("width");
|
||||||
|
preservedProperties.insert("height");
|
||||||
|
preservedProperties.insert("anchors");
|
||||||
|
// preservedProperties.insert("text ");
|
||||||
|
|
||||||
|
for (VariantProperty originalProperty : replacedNode.variantProperties()) {
|
||||||
|
VariantProperty prop;
|
||||||
|
if (preservedProperties.contains(originalProperty.name())) {
|
||||||
|
newNode.variantProperty(originalProperty.name()).setValue(originalProperty.value());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static QString readQmlFromFile(const QString& fileName)
|
||||||
|
{
|
||||||
|
QFile qmlFile(fileName);
|
||||||
|
qmlFile.open(QIODevice::ReadOnly | QIODevice::Text);
|
||||||
|
QString qmlFileContents = QString::fromUtf8(qmlFile.readAll());
|
||||||
|
return qmlFileContents;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_TestCore::testMergeModelRewriter1_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<QString>("qmlTemplateString");
|
||||||
|
QTest::addColumn<QString>("qmlStyleString");
|
||||||
|
QTest::addColumn<QString>("qmlExpectedString");
|
||||||
|
|
||||||
|
QString simpleTemplateQmlContents = readQmlFromFile(QString(TESTSRCDIR) + "/../data/merging/SimpleTemplate.qml");
|
||||||
|
QString simpleStyleQmlContents = readQmlFromFile(QString(TESTSRCDIR) + "/../data/merging/SimpleStyle.qml");
|
||||||
|
QString simpleExpectedQmlContents = readQmlFromFile(QString(TESTSRCDIR) + "/../data/merging/SimpleExpected.qml");
|
||||||
|
|
||||||
|
QString complexTemplateQmlContents = readQmlFromFile(QString(TESTSRCDIR) + "/../data/merging/ComplexTemplate.qml");
|
||||||
|
QString complexStyleQmlContents = readQmlFromFile(QString(TESTSRCDIR) + "/../data/merging/ComplexStyle.qml");
|
||||||
|
QString complexExpectedQmlContents = readQmlFromFile(QString(TESTSRCDIR) + "/../data/merging/ComplexExpected.qml");
|
||||||
|
|
||||||
|
QString emptyTemplateQmlContents = readQmlFromFile(QString(TESTSRCDIR) + "/../data/merging/EmptyTemplate.qml");
|
||||||
|
QString emptyStyleQmlContents = readQmlFromFile(QString(TESTSRCDIR) + "/../data/merging/EmptyStyle.qml");
|
||||||
|
QString emptyExpectedQmlContents = readQmlFromFile(QString(TESTSRCDIR) + "/../data/merging/EmptyExpected.qml");
|
||||||
|
|
||||||
|
QString rootReplacementTemplateQmlContents = readQmlFromFile(QString(TESTSRCDIR) + "/../data/merging/RootReplacementTemplate.qml");
|
||||||
|
QString rootReplacementStyleQmlContents = readQmlFromFile(QString(TESTSRCDIR) + "/../data/merging/RootReplacementStyle.qml");
|
||||||
|
QString rootReplacementExpectedQmlContents = readQmlFromFile(QString(TESTSRCDIR) + "/../data/merging/RootReplacementExpected.qml");
|
||||||
|
|
||||||
|
QString switchTemplateQmlContents = readQmlFromFile(QString(TESTSRCDIR) + "/../data/merging/SwitchTemplate.qml");
|
||||||
|
QString switchStyleQmlContents = readQmlFromFile(QString(TESTSRCDIR) + "/../data/merging/SwitchStyle.qml");
|
||||||
|
QString switchExpectedQmlContents = readQmlFromFile(QString(TESTSRCDIR) + "/../data/merging/SwitchExpected.qml");
|
||||||
|
|
||||||
|
QString sliderTemplateQmlContents = readQmlFromFile(QString(TESTSRCDIR) + "/../data/merging/SliderTemplate.qml");
|
||||||
|
QString sliderStyleQmlContents = readQmlFromFile(QString(TESTSRCDIR) + "/../data/merging/SliderStyle.qml");
|
||||||
|
QString sliderExpectedQmlContents = readQmlFromFile(QString(TESTSRCDIR) + "/../data/merging/SliderExpected.qml");
|
||||||
|
|
||||||
|
QString listViewTemplateQmlContents = readQmlFromFile(QString(TESTSRCDIR) + "/../data/merging/ListViewTemplate.qml");
|
||||||
|
QString listViewStyleQmlContents = readQmlFromFile(QString(TESTSRCDIR) + "/../data/merging/ListViewStyle.qml");
|
||||||
|
QString listViewExpectedQmlContents = readQmlFromFile(QString(TESTSRCDIR) + "/../data/merging/ListViewExpected.qml");
|
||||||
|
|
||||||
|
QString buttonTemplateQmlContents = readQmlFromFile(QString(TESTSRCDIR) + "/../data/merging/ButtonTemplate.qml");
|
||||||
|
QString buttonInlineStyleQmlContents = readQmlFromFile(QString(TESTSRCDIR) + "/../data/merging/ButtonStyleInline.qml");
|
||||||
|
QString buttonInlineExpectedQmlContents = readQmlFromFile(QString(TESTSRCDIR) + "/../data/merging/ButtonInlineExpected.qml");
|
||||||
|
|
||||||
|
QString buttonAbsoluteTemplateQmlContents = readQmlFromFile(QString(TESTSRCDIR) + "/../data/merging/ButtonAbsoluteTemplate.qml");
|
||||||
|
QString buttonOutlineStyleQmlContents = readQmlFromFile(QString(TESTSRCDIR) + "/../data/merging/ButtonStyleOutline.qml");
|
||||||
|
QString buttonOutlineExpectedQmlContents = readQmlFromFile(QString(TESTSRCDIR) + "/../data/merging/ButtonOutlineExpected.qml");
|
||||||
|
|
||||||
|
QTest::newRow("Simple style replacement") << simpleTemplateQmlContents << simpleStyleQmlContents << simpleExpectedQmlContents;
|
||||||
|
//QTest::newRow("Complex style replacement") << complexTemplateQmlContents << complexStyleQmlContents << complexExpectedQmlContents;
|
||||||
|
QTest::newRow("Empty stylesheet") << emptyTemplateQmlContents << emptyStyleQmlContents << emptyExpectedQmlContents;
|
||||||
|
QTest::newRow("Root node replacement") << rootReplacementTemplateQmlContents << rootReplacementStyleQmlContents << rootReplacementExpectedQmlContents;
|
||||||
|
QTest::newRow("Switch styling") << switchTemplateQmlContents << switchStyleQmlContents << switchExpectedQmlContents;
|
||||||
|
QTest::newRow("Slider styling") << sliderTemplateQmlContents << sliderStyleQmlContents << sliderExpectedQmlContents;
|
||||||
|
QTest::newRow("List View styling") << listViewTemplateQmlContents << listViewStyleQmlContents << listViewExpectedQmlContents;
|
||||||
|
QTest::newRow("Button Inline styling") << buttonTemplateQmlContents << buttonInlineStyleQmlContents << buttonInlineExpectedQmlContents;
|
||||||
|
|
||||||
|
QTest::newRow("Button Outline styling") << buttonAbsoluteTemplateQmlContents << buttonOutlineStyleQmlContents << buttonOutlineExpectedQmlContents;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_TestCore::testMergeModelRewriter1()
|
||||||
|
{
|
||||||
|
QFETCH(QString, qmlTemplateString);
|
||||||
|
QFETCH(QString, qmlStyleString);
|
||||||
|
QFETCH(QString, qmlExpectedString);
|
||||||
|
|
||||||
|
QPlainTextEdit textEdit1;
|
||||||
|
textEdit1.setPlainText(qmlTemplateString);
|
||||||
|
NotIndentingTextEditModifier textModifier1(&textEdit1);
|
||||||
|
|
||||||
|
QScopedPointer<Model> templateModel(Model::create("QtQuick.Item", 2, 1));
|
||||||
|
QVERIFY(templateModel.data());
|
||||||
|
|
||||||
|
QScopedPointer<TestView> templateView(new TestView(templateModel.data()));
|
||||||
|
templateModel->attachView(templateView.data());
|
||||||
|
|
||||||
|
// read in 1
|
||||||
|
QScopedPointer<TestRewriterView> templateRewriterView(new TestRewriterView());
|
||||||
|
templateRewriterView->setTextModifier(&textModifier1);
|
||||||
|
templateModel->attachView(templateRewriterView.data());
|
||||||
|
|
||||||
|
ModelNode templateRootNode = templateView->rootModelNode();
|
||||||
|
QVERIFY(templateRootNode.isValid());
|
||||||
|
|
||||||
|
QPlainTextEdit textEdit2;
|
||||||
|
textEdit2.setPlainText(qmlStyleString);
|
||||||
|
NotIndentingTextEditModifier textModifier2(&textEdit2);
|
||||||
|
|
||||||
|
QScopedPointer<Model> styleModel(Model::create("QtQuick.Item", 2, 1));
|
||||||
|
QVERIFY(styleModel.data());
|
||||||
|
|
||||||
|
QScopedPointer<TestView> styleView(new TestView(styleModel.data()));
|
||||||
|
styleModel->attachView(styleView.data());
|
||||||
|
|
||||||
|
// read in 2
|
||||||
|
QScopedPointer<TestRewriterView> styleRewriterView(new TestRewriterView());
|
||||||
|
styleRewriterView->setTextModifier(&textModifier2);
|
||||||
|
styleModel->attachView(styleRewriterView.data());
|
||||||
|
|
||||||
|
StylesheetMerger merger(templateView.data(), styleView.data());
|
||||||
|
merger.merge();
|
||||||
|
|
||||||
|
QCOMPARE(textEdit1.toPlainText().trimmed(), qmlExpectedString.trimmed());
|
||||||
|
}
|
||||||
|
|
||||||
void tst_TestCore::testCopyModelRewriter2()
|
void tst_TestCore::testCopyModelRewriter2()
|
||||||
{
|
{
|
||||||
const QLatin1String qmlString1("\n"
|
const QLatin1String qmlString1("\n"
|
||||||
@@ -3756,37 +3883,35 @@ void tst_TestCore::testCopyModelRewriter2()
|
|||||||
textEdit1.setPlainText(qmlString1);
|
textEdit1.setPlainText(qmlString1);
|
||||||
NotIndentingTextEditModifier textModifier1(&textEdit1);
|
NotIndentingTextEditModifier textModifier1(&textEdit1);
|
||||||
|
|
||||||
QScopedPointer<Model> model1(Model::create("QtQuick.Item", 2, 1));
|
QScopedPointer<Model> templateModel(Model::create("QtQuick.Item", 2, 1));
|
||||||
QVERIFY(model1.data());
|
QVERIFY(templateModel.data());
|
||||||
|
|
||||||
QScopedPointer<TestView> view1(new TestView(model1.data()));
|
QScopedPointer<TestView> view1(new TestView(templateModel.data()));
|
||||||
model1->attachView(view1.data());
|
templateModel->attachView(view1.data());
|
||||||
|
|
||||||
// read in 1
|
// read in 1
|
||||||
QScopedPointer<TestRewriterView> testRewriterView1(new TestRewriterView());
|
QScopedPointer<TestRewriterView> testRewriterView1(new TestRewriterView());
|
||||||
testRewriterView1->setTextModifier(&textModifier1);
|
testRewriterView1->setTextModifier(&textModifier1);
|
||||||
model1->attachView(testRewriterView1.data());
|
templateModel->attachView(testRewriterView1.data());
|
||||||
|
|
||||||
ModelNode rootNode1 = view1->rootModelNode();
|
ModelNode rootNode1 = view1->rootModelNode();
|
||||||
QVERIFY(rootNode1.isValid());
|
QVERIFY(rootNode1.isValid());
|
||||||
QCOMPARE(rootNode1.type(), QmlDesigner::TypeName("QtQuick.Rectangle"));
|
QCOMPARE(rootNode1.type(), QmlDesigner::TypeName("QtQuick.Rectangle"));
|
||||||
|
|
||||||
|
// read in 2
|
||||||
// read in 2
|
|
||||||
|
|
||||||
QPlainTextEdit textEdit2;
|
QPlainTextEdit textEdit2;
|
||||||
textEdit2.setPlainText(qmlString2);
|
textEdit2.setPlainText(qmlString2);
|
||||||
NotIndentingTextEditModifier textModifier2(&textEdit2);
|
NotIndentingTextEditModifier textModifier2(&textEdit2);
|
||||||
|
|
||||||
QScopedPointer<Model> model2(Model::create("QtQuick.Item", 2, 1));
|
QScopedPointer<Model> styleModel(Model::create("QtQuick.Item", 2, 1));
|
||||||
QVERIFY(model2.data());
|
QVERIFY(styleModel.data());
|
||||||
|
|
||||||
QScopedPointer<TestView> view2(new TestView(model2.data()));
|
QScopedPointer<TestView> view2(new TestView(styleModel.data()));
|
||||||
model2->attachView(view2.data());
|
styleModel->attachView(view2.data());
|
||||||
|
|
||||||
QScopedPointer<TestRewriterView> testRewriterView2(new TestRewriterView());
|
QScopedPointer<TestRewriterView> styleRewriterView(new TestRewriterView());
|
||||||
testRewriterView2->setTextModifier(&textModifier2);
|
styleRewriterView->setTextModifier(&textModifier2);
|
||||||
model2->attachView(testRewriterView2.data());
|
styleModel->attachView(styleRewriterView.data());
|
||||||
|
|
||||||
ModelNode rootNode2 = view2->rootModelNode();
|
ModelNode rootNode2 = view2->rootModelNode();
|
||||||
QVERIFY(rootNode2.isValid());
|
QVERIFY(rootNode2.isValid());
|
||||||
|
@@ -184,6 +184,8 @@ private slots:
|
|||||||
void testRewriterTransactionRewriter();
|
void testRewriterTransactionRewriter();
|
||||||
void testCopyModelRewriter1();
|
void testCopyModelRewriter1();
|
||||||
void testCopyModelRewriter2();
|
void testCopyModelRewriter2();
|
||||||
|
void testMergeModelRewriter1_data();
|
||||||
|
void testMergeModelRewriter1();
|
||||||
void testSubComponentManager();
|
void testSubComponentManager();
|
||||||
void testAnchorsAndRewriting();
|
void testAnchorsAndRewriting();
|
||||||
void testAnchorsAndRewritingCenter();
|
void testAnchorsAndRewritingCenter();
|
||||||
|
@@ -0,0 +1,104 @@
|
|||||||
|
import QtQuick 2.10
|
||||||
|
import QtQuick.Templates 2.1 as T
|
||||||
|
|
||||||
|
T.Button {
|
||||||
|
id: control
|
||||||
|
|
||||||
|
implicitWidth: Math.max(
|
||||||
|
background ? background.implicitWidth : 0,
|
||||||
|
contentItem.implicitWidth + leftPadding + rightPadding)
|
||||||
|
implicitHeight: Math.max(
|
||||||
|
background ? background.implicitHeight : 0,
|
||||||
|
contentItem.implicitHeight + topPadding + bottomPadding)
|
||||||
|
leftPadding: 4
|
||||||
|
rightPadding: 4
|
||||||
|
|
||||||
|
text: "My Button"
|
||||||
|
|
||||||
|
background: Item {
|
||||||
|
implicitWidth: buttonNormal.width
|
||||||
|
implicitHeight: buttonNormal.height
|
||||||
|
opacity: enabled ? 1 : 0.3
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
|
||||||
|
id: buttonNormal
|
||||||
|
color: "#d4d4d4"
|
||||||
|
width: 100 //Bit of black magic to define the default size
|
||||||
|
height: 40
|
||||||
|
|
||||||
|
border.color: "gray"
|
||||||
|
border.width: 1
|
||||||
|
radius: 2
|
||||||
|
anchors.fill: parent //binding has to be preserved
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: normalText
|
||||||
|
x: 26
|
||||||
|
y: 14 //id only required to preserve binding
|
||||||
|
text: control.text //binding has to be preserved
|
||||||
|
//anchors.fill: parent
|
||||||
|
color: "gray"
|
||||||
|
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
elide: Text.ElideRight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: buttonPressed
|
||||||
|
color: "#d4d4d4"
|
||||||
|
width: 100 //Bit of black magic to define the default size
|
||||||
|
height: 40
|
||||||
|
|
||||||
|
border.color: "gray"
|
||||||
|
border.width: 1
|
||||||
|
radius: 2
|
||||||
|
anchors.fill: parent //binding has to be preserved
|
||||||
|
|
||||||
|
Text {
|
||||||
|
x: 26
|
||||||
|
y: 14
|
||||||
|
id: pressedText //id only required to preserve binding
|
||||||
|
text: control.text //binding has to be preserved
|
||||||
|
//anchors.fill: parent
|
||||||
|
color: "black"
|
||||||
|
|
||||||
|
horizontalAlignment: Text.AlignHCenter // should not be preserved
|
||||||
|
verticalAlignment: Text.AlignVCenter // should not be preserved
|
||||||
|
elide: Text.ElideRight // should not be preserved
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
contentItem: Item {}
|
||||||
|
|
||||||
|
states: [
|
||||||
|
State {
|
||||||
|
name: "normal"
|
||||||
|
when: !control.down
|
||||||
|
PropertyChanges {
|
||||||
|
target: buttonPressed
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: buttonNormal
|
||||||
|
visible: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "down"
|
||||||
|
when: control.down
|
||||||
|
PropertyChanges {
|
||||||
|
target: buttonPressed
|
||||||
|
visible: true
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: buttonNormal
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@@ -0,0 +1,93 @@
|
|||||||
|
import QtQuick 2.10
|
||||||
|
import QtQuick.Templates 2.1 as T
|
||||||
|
|
||||||
|
T.Button {
|
||||||
|
id: control
|
||||||
|
|
||||||
|
implicitWidth: Math.max(
|
||||||
|
background ? background.implicitWidth : 0,
|
||||||
|
contentItem.implicitWidth + leftPadding + rightPadding)
|
||||||
|
implicitHeight: Math.max(
|
||||||
|
background ? background.implicitHeight : 0,
|
||||||
|
contentItem.implicitHeight + topPadding + bottomPadding)
|
||||||
|
leftPadding: 4
|
||||||
|
rightPadding: 4
|
||||||
|
|
||||||
|
text: "My Button"
|
||||||
|
|
||||||
|
background: Item {
|
||||||
|
implicitWidth: buttonNormal.width
|
||||||
|
implicitHeight: buttonNormal.height
|
||||||
|
opacity: enabled ? 1 : 0.3
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: buttonNormal
|
||||||
|
width: 100
|
||||||
|
height: 60
|
||||||
|
color: "#d4d4d4"
|
||||||
|
radius: 2
|
||||||
|
border.color: "#808080"
|
||||||
|
border.width: 1
|
||||||
|
anchors.fill: parent
|
||||||
|
Text {
|
||||||
|
id: normalText
|
||||||
|
color: "#808080"
|
||||||
|
text: control.text
|
||||||
|
elide: Text.ElideRight
|
||||||
|
anchors.fill: parent
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: buttonPressed
|
||||||
|
width: 100
|
||||||
|
height: 60
|
||||||
|
color: "#69b5ec"
|
||||||
|
radius: 2
|
||||||
|
border.color: "#808080"
|
||||||
|
border.width: 1
|
||||||
|
anchors.fill: parent
|
||||||
|
Text {
|
||||||
|
id: pressedText
|
||||||
|
color: "#000000"
|
||||||
|
text: control.text
|
||||||
|
elide: Text.ElideRight
|
||||||
|
anchors.fill: parent
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
contentItem: Item {}
|
||||||
|
|
||||||
|
states: [
|
||||||
|
State {
|
||||||
|
name: "normal"
|
||||||
|
when: !control.down
|
||||||
|
PropertyChanges {
|
||||||
|
target: buttonPressed
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: buttonNormal
|
||||||
|
visible: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "down"
|
||||||
|
when: control.down
|
||||||
|
PropertyChanges {
|
||||||
|
target: buttonPressed
|
||||||
|
visible: true
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: buttonNormal
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@@ -0,0 +1,97 @@
|
|||||||
|
import QtQuick 2.10
|
||||||
|
import QtQuick.Templates 2.1 as T
|
||||||
|
|
||||||
|
T.Button {
|
||||||
|
id: control
|
||||||
|
|
||||||
|
implicitWidth: Math.max(
|
||||||
|
background ? background.implicitWidth : 0,
|
||||||
|
contentItem.implicitWidth + leftPadding + rightPadding)
|
||||||
|
implicitHeight: Math.max(
|
||||||
|
background ? background.implicitHeight : 0,
|
||||||
|
contentItem.implicitHeight + topPadding + bottomPadding)
|
||||||
|
leftPadding: 4
|
||||||
|
rightPadding: 4
|
||||||
|
|
||||||
|
text: "My Button"
|
||||||
|
|
||||||
|
background: Item {
|
||||||
|
implicitWidth: buttonNormal.width
|
||||||
|
implicitHeight: buttonNormal.height
|
||||||
|
opacity: enabled ? 1 : 0.3
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: buttonNormal
|
||||||
|
width: 100
|
||||||
|
height: 60
|
||||||
|
color: "#d4d4d4"
|
||||||
|
radius: 2
|
||||||
|
border.color: "#808080"
|
||||||
|
border.width: 1
|
||||||
|
anchors.fill: parent
|
||||||
|
Text {
|
||||||
|
id: normalText
|
||||||
|
x: 20
|
||||||
|
y: 20
|
||||||
|
color: "#808080"
|
||||||
|
text: control.text
|
||||||
|
elide: Text.ElideRight
|
||||||
|
anchors.fill: parent
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: buttonPressed
|
||||||
|
width: 100
|
||||||
|
height: 60
|
||||||
|
color: "#69b5ec"
|
||||||
|
radius: 2
|
||||||
|
border.color: "#808080"
|
||||||
|
border.width: 1
|
||||||
|
anchors.fill: parent
|
||||||
|
Text {
|
||||||
|
id: pressedText
|
||||||
|
x: 20
|
||||||
|
y: 40
|
||||||
|
color: "#000000"
|
||||||
|
text: control.text
|
||||||
|
elide: Text.ElideRight
|
||||||
|
anchors.fill: parent
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
contentItem: Item {}
|
||||||
|
|
||||||
|
states: [
|
||||||
|
State {
|
||||||
|
name: "normal"
|
||||||
|
when: !control.down
|
||||||
|
PropertyChanges {
|
||||||
|
target: buttonPressed
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: buttonNormal
|
||||||
|
visible: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "down"
|
||||||
|
when: control.down
|
||||||
|
PropertyChanges {
|
||||||
|
target: buttonPressed
|
||||||
|
visible: true
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: buttonNormal
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@@ -0,0 +1,79 @@
|
|||||||
|
import QtQuick 2.12
|
||||||
|
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: artboard
|
||||||
|
width: 640
|
||||||
|
height: 480
|
||||||
|
color: "#ee4040"
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
|
||||||
|
id: buttonNormal
|
||||||
|
x: 286
|
||||||
|
y: 62
|
||||||
|
color: "#d4d4d4"
|
||||||
|
width: 100 //Bit of black magic to define the default size
|
||||||
|
height: 60
|
||||||
|
|
||||||
|
border.color: "gray"
|
||||||
|
border.width: 1
|
||||||
|
radius: 2
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: normalText //id only required to preserve binding
|
||||||
|
//binding has to be preserved
|
||||||
|
anchors.fill: parent //binding has to be preserved
|
||||||
|
color: "gray"
|
||||||
|
text: "Normal"
|
||||||
|
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
//luckily enums are interpreted as variant properties and not bindings
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
elide: Text.ElideRight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: buttonPressed
|
||||||
|
x: 123
|
||||||
|
y: 62
|
||||||
|
color: "#69b5ec"
|
||||||
|
width: 100 //Bit of black magic to define the default size
|
||||||
|
height: 60
|
||||||
|
|
||||||
|
border.color: "gray"
|
||||||
|
border.width: 1
|
||||||
|
radius: 2
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: pressedText //id only required to preserve binding
|
||||||
|
//binding has to be preserved
|
||||||
|
anchors.fill: parent
|
||||||
|
color: "black"
|
||||||
|
text: "pressed"
|
||||||
|
|
||||||
|
horizontalAlignment: Text.AlignHCenter // should not be preserved -
|
||||||
|
//luckily enums are interpreted as variant properties and not bindings
|
||||||
|
verticalAlignment: Text.AlignVCenter // should not be preserved
|
||||||
|
elide: Text.ElideRight // should not be preserved
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: element
|
||||||
|
x: 1
|
||||||
|
y: 362
|
||||||
|
color: "#eaeaea"
|
||||||
|
text: qsTrId("Some stuff for reference that is thrown away")
|
||||||
|
font.pixelSize: 32
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*##^##
|
||||||
|
Designer {
|
||||||
|
D{i:0;formeditorColor:"#000000"}
|
||||||
|
}
|
||||||
|
##^##*/
|
@@ -0,0 +1,83 @@
|
|||||||
|
import QtQuick 2.12
|
||||||
|
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: artboard
|
||||||
|
width: 640
|
||||||
|
height: 480
|
||||||
|
color: "#ee4040"
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
|
||||||
|
id: buttonNormal
|
||||||
|
x: 286
|
||||||
|
y: 62
|
||||||
|
color: "#d4d4d4"
|
||||||
|
width: 100 //Bit of black magic to define the default size
|
||||||
|
height: 60
|
||||||
|
|
||||||
|
border.color: "gray"
|
||||||
|
border.width: 1
|
||||||
|
radius: 2
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
x: 319
|
||||||
|
y: 86
|
||||||
|
id: normalText //id only required to preserve binding
|
||||||
|
//binding has to be preserved
|
||||||
|
|
||||||
|
color: "gray"
|
||||||
|
text: "Normal"
|
||||||
|
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
//luckily enums are interpreted as variant properties and not bindings
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
elide: Text.ElideRight
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: buttonPressed
|
||||||
|
x: 123
|
||||||
|
y: 62
|
||||||
|
color: "#69b5ec"
|
||||||
|
width: 100 //Bit of black magic to define the default size
|
||||||
|
height: 60
|
||||||
|
|
||||||
|
border.color: "gray"
|
||||||
|
border.width: 1
|
||||||
|
radius: 2
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
x: 154
|
||||||
|
y: 86
|
||||||
|
id: pressedText //id only required to preserve binding
|
||||||
|
//binding has to be preserved
|
||||||
|
//anchors.fill: parent
|
||||||
|
color: "black"
|
||||||
|
text: "pressed"
|
||||||
|
|
||||||
|
horizontalAlignment: Text.AlignHCenter // should not be preserved -
|
||||||
|
//luckily enums are interpreted as variant properties and not bindings
|
||||||
|
verticalAlignment: Text.AlignVCenter // should not be preserved
|
||||||
|
elide: Text.ElideRight // should not be preserved
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: element
|
||||||
|
x: 1
|
||||||
|
y: 362
|
||||||
|
color: "#eaeaea"
|
||||||
|
text: qsTrId("Some stuff for reference that is thrown away")
|
||||||
|
font.pixelSize: 32
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*##^##
|
||||||
|
Designer {
|
||||||
|
D{i:0;formeditorColor:"#000000"}
|
||||||
|
}
|
||||||
|
##^##*/
|
100
tests/auto/qml/qmldesigner/data/merging/ButtonTemplate.qml
Normal file
100
tests/auto/qml/qmldesigner/data/merging/ButtonTemplate.qml
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
import QtQuick 2.10
|
||||||
|
import QtQuick.Templates 2.1 as T
|
||||||
|
|
||||||
|
T.Button {
|
||||||
|
id: control
|
||||||
|
|
||||||
|
implicitWidth: Math.max(
|
||||||
|
background ? background.implicitWidth : 0,
|
||||||
|
contentItem.implicitWidth + leftPadding + rightPadding)
|
||||||
|
implicitHeight: Math.max(
|
||||||
|
background ? background.implicitHeight : 0,
|
||||||
|
contentItem.implicitHeight + topPadding + bottomPadding)
|
||||||
|
leftPadding: 4
|
||||||
|
rightPadding: 4
|
||||||
|
|
||||||
|
text: "My Button"
|
||||||
|
|
||||||
|
background: Item {
|
||||||
|
implicitWidth: buttonNormal.width
|
||||||
|
implicitHeight: buttonNormal.height
|
||||||
|
opacity: enabled ? 1 : 0.3
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
|
||||||
|
id: buttonNormal
|
||||||
|
color: "#d4d4d4"
|
||||||
|
width: 100 //Bit of black magic to define the default size
|
||||||
|
height: 40
|
||||||
|
|
||||||
|
border.color: "gray"
|
||||||
|
border.width: 1
|
||||||
|
radius: 2
|
||||||
|
anchors.fill: parent //binding has to be preserved
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: normalText //id only required to preserve binding
|
||||||
|
text: control.text //binding has to be preserved
|
||||||
|
anchors.fill: parent
|
||||||
|
color: "gray"
|
||||||
|
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
elide: Text.ElideRight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: buttonPressed
|
||||||
|
color: "#d4d4d4"
|
||||||
|
width: 100 //Bit of black magic to define the default size
|
||||||
|
height: 40
|
||||||
|
|
||||||
|
border.color: "gray"
|
||||||
|
border.width: 1
|
||||||
|
radius: 2
|
||||||
|
anchors.fill: parent //binding has to be preserved
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: pressedText //id only required to preserve binding
|
||||||
|
text: control.text //binding has to be preserved
|
||||||
|
anchors.fill: parent
|
||||||
|
color: "black"
|
||||||
|
|
||||||
|
horizontalAlignment: Text.AlignHCenter // should not be preserved
|
||||||
|
verticalAlignment: Text.AlignVCenter // should not be preserved
|
||||||
|
elide: Text.ElideRight // should not be preserved
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
contentItem: Item {}
|
||||||
|
|
||||||
|
states: [
|
||||||
|
State {
|
||||||
|
name: "normal"
|
||||||
|
when: !control.down
|
||||||
|
PropertyChanges {
|
||||||
|
target: buttonPressed
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: buttonNormal
|
||||||
|
visible: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "down"
|
||||||
|
when: control.down
|
||||||
|
PropertyChanges {
|
||||||
|
target: buttonPressed
|
||||||
|
visible: true
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: buttonNormal
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
62
tests/auto/qml/qmldesigner/data/merging/ComplexExpected.qml
Normal file
62
tests/auto/qml/qmldesigner/data/merging/ComplexExpected.qml
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
import QtQuick 2.1
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: root
|
||||||
|
x: 10;
|
||||||
|
y: 10;
|
||||||
|
Rectangle {
|
||||||
|
id: rectangle0
|
||||||
|
x: 10
|
||||||
|
y: 10
|
||||||
|
width: 200
|
||||||
|
height: 150
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: rectangle1
|
||||||
|
x: 10
|
||||||
|
y: 10
|
||||||
|
width: 100
|
||||||
|
height: 150
|
||||||
|
source: "qt/icon.png"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: rectangle2
|
||||||
|
x: 100;
|
||||||
|
y: 100;
|
||||||
|
anchors.fill: root
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: rectangle3
|
||||||
|
x: 140;
|
||||||
|
y: 180;
|
||||||
|
gradient: Gradient {
|
||||||
|
GradientStop {
|
||||||
|
position: 0
|
||||||
|
color: "white"
|
||||||
|
}
|
||||||
|
GradientStop {
|
||||||
|
position: 1
|
||||||
|
color: "black"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Image {
|
||||||
|
id: rectangle4
|
||||||
|
x: 10
|
||||||
|
y: 20
|
||||||
|
width: 200
|
||||||
|
height: 50
|
||||||
|
Rectangle {
|
||||||
|
id: rectangle5
|
||||||
|
x: 10
|
||||||
|
y: 20
|
||||||
|
width: 200
|
||||||
|
height: 50
|
||||||
|
}
|
||||||
|
source: "qt/realcool.jpg"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
45
tests/auto/qml/qmldesigner/data/merging/ComplexStyle.qml
Normal file
45
tests/auto/qml/qmldesigner/data/merging/ComplexStyle.qml
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
import QtQuick 2.1
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Rectangle {
|
||||||
|
id: rectangle0
|
||||||
|
Image {
|
||||||
|
id: rectangle1
|
||||||
|
x: 10
|
||||||
|
y: 10
|
||||||
|
height: 150
|
||||||
|
width: 100
|
||||||
|
source: "qt/icon.png"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Rectangle {
|
||||||
|
id: rectangle3
|
||||||
|
x: 140;
|
||||||
|
y: 180;
|
||||||
|
gradient: Gradient {
|
||||||
|
GradientStop {
|
||||||
|
position: 0
|
||||||
|
color: "white"
|
||||||
|
}
|
||||||
|
GradientStop {
|
||||||
|
position: 1
|
||||||
|
color: "black"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Rectangle {
|
||||||
|
id: rectangle5
|
||||||
|
x: 10
|
||||||
|
y: 20
|
||||||
|
width: 200
|
||||||
|
height: 50
|
||||||
|
}
|
||||||
|
Image {
|
||||||
|
id: rectangle4
|
||||||
|
x: 10;
|
||||||
|
y: 10;
|
||||||
|
height: 150
|
||||||
|
width: 100
|
||||||
|
source: "qt/realcool.jpg"
|
||||||
|
}
|
||||||
|
}
|
49
tests/auto/qml/qmldesigner/data/merging/ComplexTemplate.qml
Normal file
49
tests/auto/qml/qmldesigner/data/merging/ComplexTemplate.qml
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
import QtQuick 2.1
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: root
|
||||||
|
x: 10;
|
||||||
|
y: 10;
|
||||||
|
Rectangle {
|
||||||
|
id: rectangle0
|
||||||
|
x: 10;
|
||||||
|
y: 10;
|
||||||
|
height: 150
|
||||||
|
width: 200
|
||||||
|
}
|
||||||
|
Rectangle {
|
||||||
|
id: rectangle2
|
||||||
|
x: 100;
|
||||||
|
y: 100;
|
||||||
|
anchors.fill: root
|
||||||
|
}
|
||||||
|
Rectangle {
|
||||||
|
id: rectangle3
|
||||||
|
x: 140;
|
||||||
|
y: 180;
|
||||||
|
gradient: Gradient {
|
||||||
|
GradientStop {
|
||||||
|
position: 0
|
||||||
|
color: "black"
|
||||||
|
}
|
||||||
|
GradientStop {
|
||||||
|
position: 1
|
||||||
|
color: "white"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Rectangle {
|
||||||
|
id: rectangle4
|
||||||
|
x: 10
|
||||||
|
y: 20
|
||||||
|
width: 200
|
||||||
|
height: 50
|
||||||
|
Rectangle {
|
||||||
|
id: rectangle5
|
||||||
|
x: 10
|
||||||
|
y: 20
|
||||||
|
width: 200
|
||||||
|
height: 50
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,43 @@
|
|||||||
|
// Test that an empty style sheet will leave the original template untouched.
|
||||||
|
import QtQuick 2.1
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: root
|
||||||
|
x: 10;
|
||||||
|
y: 10;
|
||||||
|
Rectangle {
|
||||||
|
id: rectangle0
|
||||||
|
x: 10;
|
||||||
|
y: 10;
|
||||||
|
height: 150
|
||||||
|
width: 200
|
||||||
|
}
|
||||||
|
Rectangle {
|
||||||
|
id: rectangle2
|
||||||
|
x: 100;
|
||||||
|
y: 100;
|
||||||
|
anchors.fill: root
|
||||||
|
}
|
||||||
|
Rectangle {
|
||||||
|
id: rectangle3
|
||||||
|
x: 140;
|
||||||
|
y: 180;
|
||||||
|
gradient: Gradient {
|
||||||
|
GradientStop {
|
||||||
|
position: 0
|
||||||
|
color: "white"
|
||||||
|
}
|
||||||
|
GradientStop {
|
||||||
|
position: 1
|
||||||
|
color: "black"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Rectangle {
|
||||||
|
id: rectangle4
|
||||||
|
x: 10
|
||||||
|
y: 20
|
||||||
|
width: 200
|
||||||
|
height: 50
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1 @@
|
|||||||
|
import QtQuick 2.1
|
@@ -0,0 +1,43 @@
|
|||||||
|
// Test that an empty style sheet will leave the original template untouched.
|
||||||
|
import QtQuick 2.1
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: root
|
||||||
|
x: 10;
|
||||||
|
y: 10;
|
||||||
|
Rectangle {
|
||||||
|
id: rectangle0
|
||||||
|
x: 10;
|
||||||
|
y: 10;
|
||||||
|
height: 150
|
||||||
|
width: 200
|
||||||
|
}
|
||||||
|
Rectangle {
|
||||||
|
id: rectangle2
|
||||||
|
x: 100;
|
||||||
|
y: 100;
|
||||||
|
anchors.fill: root
|
||||||
|
}
|
||||||
|
Rectangle {
|
||||||
|
id: rectangle3
|
||||||
|
x: 140;
|
||||||
|
y: 180;
|
||||||
|
gradient: Gradient {
|
||||||
|
GradientStop {
|
||||||
|
position: 0
|
||||||
|
color: "white"
|
||||||
|
}
|
||||||
|
GradientStop {
|
||||||
|
position: 1
|
||||||
|
color: "black"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Rectangle {
|
||||||
|
id: rectangle4
|
||||||
|
x: 10
|
||||||
|
y: 20
|
||||||
|
width: 200
|
||||||
|
height: 50
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
135
tests/auto/qml/qmldesigner/data/merging/ListViewExpected.qml
Normal file
135
tests/auto/qml/qmldesigner/data/merging/ListViewExpected.qml
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
import QtQuick 2.10
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
id: view
|
||||||
|
width: listViewBackground.width
|
||||||
|
height: listViewBackground.height
|
||||||
|
highlight: Rectangle {
|
||||||
|
id: listViewHighLight
|
||||||
|
width: view.width
|
||||||
|
height: 120
|
||||||
|
color: "#343434"
|
||||||
|
radius: 4
|
||||||
|
border.color: "#0d52a4"
|
||||||
|
border.width: 8
|
||||||
|
}
|
||||||
|
|
||||||
|
highlightMoveDuration: 0
|
||||||
|
|
||||||
|
children: [
|
||||||
|
Item {
|
||||||
|
z: -1
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: listViewBackground
|
||||||
|
width: 420
|
||||||
|
height: 420
|
||||||
|
color: "#69b5ec"
|
||||||
|
anchors.fill: parent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
model: ListModel {
|
||||||
|
ListElement {
|
||||||
|
name: "Music"
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "Movies"
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "Camera"
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "Map"
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "Calendar"
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "Messaging"
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "Todo List"
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "Contacts"
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "Settings"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
delegate: Item {
|
||||||
|
id: delegate
|
||||||
|
width: ListView.view.width
|
||||||
|
height: delegateNormal.height
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: delegateNormal
|
||||||
|
width: 420
|
||||||
|
height: 120
|
||||||
|
visible: true
|
||||||
|
color: "#bdbdbd"
|
||||||
|
radius: 4
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: 12
|
||||||
|
Text {
|
||||||
|
id: labelNormal
|
||||||
|
color: "#343434"
|
||||||
|
text: name
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.margins: 24
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: delegateHighlighted
|
||||||
|
width: 420
|
||||||
|
height: 120
|
||||||
|
visible: false
|
||||||
|
color: "#8125eb29"
|
||||||
|
radius: 4
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: 12
|
||||||
|
Text {
|
||||||
|
id: labelHighlighted
|
||||||
|
color: "#efefef"
|
||||||
|
text: name
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.margins: 52
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: delegate.ListView.view.currentIndex = index
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
states: [
|
||||||
|
State {
|
||||||
|
name: "Highlighted"
|
||||||
|
|
||||||
|
when: delegate.ListView.isCurrentItem
|
||||||
|
PropertyChanges {
|
||||||
|
target: delegateHighlighted
|
||||||
|
visible: true
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: delegateNormal
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
82
tests/auto/qml/qmldesigner/data/merging/ListViewStyle.qml
Normal file
82
tests/auto/qml/qmldesigner/data/merging/ListViewStyle.qml
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
import QtQuick 2.12
|
||||||
|
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: artboard
|
||||||
|
width: 800
|
||||||
|
height: 600
|
||||||
|
color: "#ee4040"
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: listViewBackground
|
||||||
|
x: 19
|
||||||
|
y: 34
|
||||||
|
width: 420
|
||||||
|
height: 420
|
||||||
|
|
||||||
|
color: "#69b5ec"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: delegateNormal
|
||||||
|
x: 19
|
||||||
|
y: 51
|
||||||
|
color: "#bdbdbd"
|
||||||
|
|
||||||
|
height: 120
|
||||||
|
|
||||||
|
width: 420
|
||||||
|
|
||||||
|
radius: 4
|
||||||
|
Text {
|
||||||
|
id: labelNormal //id required for binding preservation
|
||||||
|
color: "#343434"
|
||||||
|
text: "some text"
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
|
||||||
|
anchors.margins: 24
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: delegateHighlighted
|
||||||
|
x: 19
|
||||||
|
y: 177
|
||||||
|
color: "#8125eb29"
|
||||||
|
height: 120
|
||||||
|
|
||||||
|
width: 420
|
||||||
|
|
||||||
|
radius: 4
|
||||||
|
Text {
|
||||||
|
id: labelHighlighted //id required for binding preservation
|
||||||
|
color: "#efefef"
|
||||||
|
text: "some text"
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
|
||||||
|
anchors.margins: 52
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: listViewHighLight
|
||||||
|
x: 19
|
||||||
|
y: 323
|
||||||
|
width: 420
|
||||||
|
height: 120
|
||||||
|
color: "#343434"
|
||||||
|
radius: 4
|
||||||
|
border.color: "#0d52a4"
|
||||||
|
border.width: 8
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
133
tests/auto/qml/qmldesigner/data/merging/ListViewTemplate.qml
Normal file
133
tests/auto/qml/qmldesigner/data/merging/ListViewTemplate.qml
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
import QtQuick 2.10
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
id: view
|
||||||
|
width: listViewBackground.width
|
||||||
|
height: listViewBackground.height
|
||||||
|
|
||||||
|
highlightMoveDuration: 0
|
||||||
|
|
||||||
|
children: [
|
||||||
|
Item {
|
||||||
|
z: -1
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: listViewBackground
|
||||||
|
width: 420
|
||||||
|
height: 420
|
||||||
|
|
||||||
|
color: "#d80e0e"
|
||||||
|
anchors.fill: parent // hsa to be preserved
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
model: ListModel {
|
||||||
|
ListElement {
|
||||||
|
name: "Music"
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "Movies"
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "Camera"
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "Map"
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "Calendar"
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "Messaging"
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "Todo List"
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "Contacts"
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "Settings"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
highlight: Rectangle {
|
||||||
|
id: listViewHighLight
|
||||||
|
width: view.width // has to be preserved
|
||||||
|
height: 120
|
||||||
|
color: "#343434"
|
||||||
|
radius: 4
|
||||||
|
border.color: "#0d52a4"
|
||||||
|
border.width: 8
|
||||||
|
}
|
||||||
|
|
||||||
|
delegate: Item {
|
||||||
|
id: delegate
|
||||||
|
width: ListView.view.width
|
||||||
|
height: delegateNormal.height
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: delegateNormal
|
||||||
|
color: "#bdbdbd"
|
||||||
|
anchors.fill: parent
|
||||||
|
height: 140
|
||||||
|
anchors.margins: 12
|
||||||
|
visible: true
|
||||||
|
radius: 4
|
||||||
|
Text {
|
||||||
|
id: labelNormal //id required for binding preservation
|
||||||
|
color: "#343434"
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
|
||||||
|
text: name
|
||||||
|
anchors.margins: 24
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: delegateHighlighted
|
||||||
|
color: "#36bdbdbd"
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: 12
|
||||||
|
visible: false
|
||||||
|
radius: 4
|
||||||
|
Text {
|
||||||
|
id: labelHighlighted //id required for binding preservation
|
||||||
|
color: "#efefef"
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
|
||||||
|
text: name
|
||||||
|
anchors.margins: 32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: delegate.ListView.view.currentIndex = index
|
||||||
|
}
|
||||||
|
states: [
|
||||||
|
State {
|
||||||
|
name: "Highlighted"
|
||||||
|
|
||||||
|
when: delegate.ListView.isCurrentItem
|
||||||
|
PropertyChanges {
|
||||||
|
target: delegateHighlighted
|
||||||
|
visible: true
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: delegateNormal
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,26 @@
|
|||||||
|
import QtQuick 2.1
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: rectangle0
|
||||||
|
Image {
|
||||||
|
id: rectangle1
|
||||||
|
x: 10
|
||||||
|
y: 10
|
||||||
|
width: 100
|
||||||
|
height: 150
|
||||||
|
source: "qt/icon.png"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: rectangle4
|
||||||
|
x: 10
|
||||||
|
y: 10
|
||||||
|
width: 100
|
||||||
|
height: 150
|
||||||
|
source: "qt/realcool.jpg"
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,24 @@
|
|||||||
|
import QtQuick 2.1
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
Rectangle {
|
||||||
|
id: rectangle0
|
||||||
|
Image {
|
||||||
|
id: rectangle1
|
||||||
|
x: 10
|
||||||
|
y: 10
|
||||||
|
height: 150
|
||||||
|
width: 100
|
||||||
|
source: "qt/icon.png"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Image {
|
||||||
|
id: rectangle4
|
||||||
|
x: 10;
|
||||||
|
y: 10;
|
||||||
|
height: 150
|
||||||
|
width: 100
|
||||||
|
source: "qt/realcool.jpg"
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,35 @@
|
|||||||
|
import QtQuick 2.1
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: root
|
||||||
|
x: 10;
|
||||||
|
y: 10;
|
||||||
|
Rectangle {
|
||||||
|
id: rectangle1
|
||||||
|
x: 10;
|
||||||
|
y: 10;
|
||||||
|
height: 150
|
||||||
|
width: 200
|
||||||
|
}
|
||||||
|
Rectangle {
|
||||||
|
id: rectangle2
|
||||||
|
x: 100;
|
||||||
|
y: 100;
|
||||||
|
anchors.fill: root
|
||||||
|
}
|
||||||
|
Rectangle {
|
||||||
|
id: rectangle3
|
||||||
|
x: 140;
|
||||||
|
y: 180;
|
||||||
|
gradient: Gradient {
|
||||||
|
GradientStop {
|
||||||
|
position: 0
|
||||||
|
color: "white"
|
||||||
|
}
|
||||||
|
GradientStop {
|
||||||
|
position: 1
|
||||||
|
color: "black"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
38
tests/auto/qml/qmldesigner/data/merging/SimpleExpected.qml
Normal file
38
tests/auto/qml/qmldesigner/data/merging/SimpleExpected.qml
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
import QtQuick 2.1
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: root
|
||||||
|
x: 10;
|
||||||
|
y: 10;
|
||||||
|
Image {
|
||||||
|
id: rectangle1
|
||||||
|
x: 10
|
||||||
|
y: 10
|
||||||
|
width: 100
|
||||||
|
height: 150
|
||||||
|
source: "qt/icon.png"
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: rectangle2
|
||||||
|
x: 100;
|
||||||
|
y: 100;
|
||||||
|
anchors.fill: root
|
||||||
|
}
|
||||||
|
Rectangle {
|
||||||
|
id: rectangle3
|
||||||
|
x: 140;
|
||||||
|
y: 180;
|
||||||
|
gradient: Gradient {
|
||||||
|
GradientStop {
|
||||||
|
position: 0
|
||||||
|
color: "white"
|
||||||
|
}
|
||||||
|
GradientStop {
|
||||||
|
position: 1
|
||||||
|
color: "black"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
10
tests/auto/qml/qmldesigner/data/merging/SimpleStyle.qml
Normal file
10
tests/auto/qml/qmldesigner/data/merging/SimpleStyle.qml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import QtQuick 2.1
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: rectangle1
|
||||||
|
x: 10;
|
||||||
|
y: 10;
|
||||||
|
height: 150
|
||||||
|
width: 100
|
||||||
|
source: "qt/icon.png"
|
||||||
|
}
|
38
tests/auto/qml/qmldesigner/data/merging/SimpleTemplate.qml
Normal file
38
tests/auto/qml/qmldesigner/data/merging/SimpleTemplate.qml
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
import QtQuick 2.1
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: root
|
||||||
|
x: 10;
|
||||||
|
y: 10;
|
||||||
|
Rectangle {
|
||||||
|
id: rectangle1
|
||||||
|
x: 10;
|
||||||
|
y: 10;
|
||||||
|
height: 150
|
||||||
|
width: 200
|
||||||
|
}
|
||||||
|
Rectangle {
|
||||||
|
id: rectangle2
|
||||||
|
x: 100;
|
||||||
|
y: 100;
|
||||||
|
anchors.fill: root
|
||||||
|
}
|
||||||
|
Rectangle {
|
||||||
|
id: rectangle3
|
||||||
|
x: 140;
|
||||||
|
y: 180;
|
||||||
|
gradient: Gradient {
|
||||||
|
GradientStop {
|
||||||
|
position: 0
|
||||||
|
color: "white"
|
||||||
|
}
|
||||||
|
GradientStop {
|
||||||
|
position: 1
|
||||||
|
color: "black"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
68
tests/auto/qml/qmldesigner/data/merging/SliderExpected.qml
Normal file
68
tests/auto/qml/qmldesigner/data/merging/SliderExpected.qml
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
import QtQuick 2.6
|
||||||
|
import QtQuick.Controls 2.0
|
||||||
|
|
||||||
|
Slider {
|
||||||
|
id: control
|
||||||
|
value: 0.5
|
||||||
|
|
||||||
|
background: Item {
|
||||||
|
x: control.leftPadding
|
||||||
|
y: control.topPadding + control.availableHeight / 2 - height / 2
|
||||||
|
implicitWidth: sliderGroove.width
|
||||||
|
implicitHeight: sliderGroove.height
|
||||||
|
height: implicitHeight
|
||||||
|
width: control.availableWidth
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: sliderGroove
|
||||||
|
width: 200
|
||||||
|
height: 6
|
||||||
|
color: "#bdbebf"
|
||||||
|
radius: 2
|
||||||
|
anchors.fill: parent
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
width: control.visualPosition * sliderGroove.width // should be preserved
|
||||||
|
height: sliderGrooveLeft.height
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: sliderGrooveLeft
|
||||||
|
width: 200
|
||||||
|
height: 6
|
||||||
|
color: "#21be2b"
|
||||||
|
radius: 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
handle: Item {
|
||||||
|
x: control.leftPadding + control.visualPosition * (control.availableWidth - width)
|
||||||
|
y: control.topPadding + control.availableHeight / 2 - height / 2
|
||||||
|
|
||||||
|
implicitWidth: handleNormal.width
|
||||||
|
implicitHeight: handleNormal.height
|
||||||
|
Rectangle {
|
||||||
|
id: handleNormal
|
||||||
|
width: 32
|
||||||
|
height: 32
|
||||||
|
visible: !control.pressed
|
||||||
|
color: "#f6f6f6"
|
||||||
|
radius: 13
|
||||||
|
border.color: "#bdbebf"
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: handlePressed
|
||||||
|
width: 32
|
||||||
|
height: 32
|
||||||
|
visible: control.pressed
|
||||||
|
color: "#221bdb"
|
||||||
|
radius: 13
|
||||||
|
border.color: "#bdbebf"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
65
tests/auto/qml/qmldesigner/data/merging/SliderStyle.qml
Normal file
65
tests/auto/qml/qmldesigner/data/merging/SliderStyle.qml
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
import QtQuick 2.12
|
||||||
|
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: artboard
|
||||||
|
width: 640
|
||||||
|
height: 480
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: sliderGroove
|
||||||
|
x: 78
|
||||||
|
y: 127
|
||||||
|
width: 200
|
||||||
|
height: 6
|
||||||
|
color: "#bdbebf"
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: sliderGrooveLeft
|
||||||
|
x: 78
|
||||||
|
y: 165
|
||||||
|
width: 200
|
||||||
|
height: 6
|
||||||
|
color: "#21be2b"
|
||||||
|
radius: 2
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: handleNormal
|
||||||
|
x: 130
|
||||||
|
y: 74
|
||||||
|
width: 32
|
||||||
|
height: 32
|
||||||
|
radius: 13
|
||||||
|
color: "#f6f6f6"
|
||||||
|
border.color: "#bdbebf"
|
||||||
|
}
|
||||||
|
Rectangle {
|
||||||
|
id: handlePressed
|
||||||
|
x: 78
|
||||||
|
y: 74
|
||||||
|
width: 32
|
||||||
|
height: 32
|
||||||
|
radius: 13
|
||||||
|
color: "#221bdb"
|
||||||
|
border.color: "#bdbebf"
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: element
|
||||||
|
x: 8
|
||||||
|
y: 320
|
||||||
|
color: "#eaeaea"
|
||||||
|
text: qsTrId("Some stuff for reference that is thrown away")
|
||||||
|
font.pixelSize: 32
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*##^##
|
||||||
|
Designer {
|
||||||
|
D{i:0;formeditorColor:"#000000"}
|
||||||
|
}
|
||||||
|
##^##*/
|
66
tests/auto/qml/qmldesigner/data/merging/SliderTemplate.qml
Normal file
66
tests/auto/qml/qmldesigner/data/merging/SliderTemplate.qml
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
import QtQuick 2.6
|
||||||
|
import QtQuick.Controls 2.0
|
||||||
|
|
||||||
|
Slider {
|
||||||
|
id: control
|
||||||
|
value: 0.5
|
||||||
|
|
||||||
|
background: Item {
|
||||||
|
x: control.leftPadding
|
||||||
|
y: control.topPadding + control.availableHeight / 2 - height / 2
|
||||||
|
implicitWidth: sliderGroove.width
|
||||||
|
implicitHeight: sliderGroove.height
|
||||||
|
height: implicitHeight
|
||||||
|
width: control.availableWidth
|
||||||
|
Rectangle {
|
||||||
|
id: sliderGroove
|
||||||
|
|
||||||
|
width: 200
|
||||||
|
height: 4
|
||||||
|
|
||||||
|
anchors.fill: parent // has to be preserved
|
||||||
|
radius: 2
|
||||||
|
color: "#bdbebf"
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
width: control.visualPosition * sliderGroove.width // should be preserved
|
||||||
|
height: sliderGrooveLeft.height
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: sliderGrooveLeft
|
||||||
|
width: 200
|
||||||
|
height: 4
|
||||||
|
color: "#21be2b"
|
||||||
|
radius: 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handle: Item {
|
||||||
|
x: control.leftPadding + control.visualPosition * (control.availableWidth - width)
|
||||||
|
y: control.topPadding + control.availableHeight / 2 - height / 2
|
||||||
|
|
||||||
|
implicitWidth: handleNormal.width
|
||||||
|
implicitHeight: handleNormal.height
|
||||||
|
Rectangle {
|
||||||
|
id: handleNormal
|
||||||
|
width: 26
|
||||||
|
height: 26
|
||||||
|
radius: 13
|
||||||
|
color: "#f6f6f6"
|
||||||
|
visible: !control.pressed //has to be preserved
|
||||||
|
border.color: "#bdbebf"
|
||||||
|
}
|
||||||
|
Rectangle {
|
||||||
|
id: handlePressed
|
||||||
|
width: 26
|
||||||
|
height: 26
|
||||||
|
radius: 13
|
||||||
|
visible: control.pressed //has to be preserved
|
||||||
|
color: "#f0f0f0"
|
||||||
|
border.color: "#bdbebf"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
111
tests/auto/qml/qmldesigner/data/merging/SwitchExpected.qml
Normal file
111
tests/auto/qml/qmldesigner/data/merging/SwitchExpected.qml
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
import QtQuick 2.10
|
||||||
|
import QtQuick.Templates 2.1 as T
|
||||||
|
import TemplateMerging 1.0
|
||||||
|
|
||||||
|
T.Switch {
|
||||||
|
id: control
|
||||||
|
|
||||||
|
implicitWidth: background.implicitWidth
|
||||||
|
implicitHeight: background.implicitHeight
|
||||||
|
|
||||||
|
text: "test"
|
||||||
|
indicator: Rectangle {
|
||||||
|
id: switchIndicator
|
||||||
|
x: control.leftPadding
|
||||||
|
y: 34
|
||||||
|
width: 64
|
||||||
|
height: 44
|
||||||
|
color: "#e9e9e9"
|
||||||
|
radius: 16
|
||||||
|
border.color: "#dddddd"
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
Rectangle {
|
||||||
|
id: switchHandle
|
||||||
|
width: 31
|
||||||
|
height: 44
|
||||||
|
color: "#e9e9e9"
|
||||||
|
radius: 16
|
||||||
|
border.color: "#808080"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
background: Item {
|
||||||
|
implicitWidth: switchBackground.width
|
||||||
|
implicitHeight: switchBackground.height
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: switchBackground
|
||||||
|
width: 144
|
||||||
|
height: 52
|
||||||
|
color: "#c2c2c2"
|
||||||
|
border.color: "#808080"
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: "background"
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: 12
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
leftPadding: 4
|
||||||
|
|
||||||
|
contentItem: Item { //designer want to edit the label as part of background
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
states: [
|
||||||
|
State {
|
||||||
|
name: "off"
|
||||||
|
when: !control.checked && !control.down
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "on"
|
||||||
|
when: control.checked && !control.down
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: switchIndicator
|
||||||
|
color: "#1713de"
|
||||||
|
border.color: "#1713de"
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: switchHandle
|
||||||
|
x: parent.width - width
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "off_down"
|
||||||
|
when: !control.checked && control.down
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: switchIndicator
|
||||||
|
color: "#e9e9e9"
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: switchHandle
|
||||||
|
color: "#d2d2d2"
|
||||||
|
border.color: "#d2d2d2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "on_down"
|
||||||
|
when: control.checked && control.down
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: switchHandle
|
||||||
|
x: parent.width - width
|
||||||
|
color: "#e9e9e9"
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: switchIndicator
|
||||||
|
color: "#030381"
|
||||||
|
border.color: "#030381"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
66
tests/auto/qml/qmldesigner/data/merging/SwitchStyle.qml
Normal file
66
tests/auto/qml/qmldesigner/data/merging/SwitchStyle.qml
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
import QtQuick 2.12
|
||||||
|
|
||||||
|
Item {
|
||||||
|
width: 640
|
||||||
|
height: 480
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: switchIndicator
|
||||||
|
x: 219
|
||||||
|
y: 34
|
||||||
|
width: 64
|
||||||
|
height: 44
|
||||||
|
|
||||||
|
color: "#e9e9e9"
|
||||||
|
|
||||||
|
radius: 16
|
||||||
|
border.color: "#dddddd"
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: switchHandle //id is required for states
|
||||||
|
|
||||||
|
width: 31
|
||||||
|
height: 44
|
||||||
|
radius: 16
|
||||||
|
color: "#e9e9e9"
|
||||||
|
border.color: "#808080"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: switchBackground
|
||||||
|
x: 346
|
||||||
|
y: 27
|
||||||
|
width: 144
|
||||||
|
height: 52
|
||||||
|
color: "#c2c2c2"
|
||||||
|
border.color: "#808080"
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: switchBackgroundText
|
||||||
|
text: "background"
|
||||||
|
anchors.right: parent.right
|
||||||
|
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.rightMargin: 12
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: element
|
||||||
|
x: 1
|
||||||
|
y: 362
|
||||||
|
color: "#eaeaea"
|
||||||
|
text: qsTrId("Some stuff for reference that is thrown away")
|
||||||
|
font.pixelSize: 32
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle { //This is ignored when merging
|
||||||
|
id: weirdStuff02
|
||||||
|
x: 8
|
||||||
|
y: 87
|
||||||
|
width: 624
|
||||||
|
height: 200
|
||||||
|
color: "#ffffff"
|
||||||
|
}
|
||||||
|
}
|
120
tests/auto/qml/qmldesigner/data/merging/SwitchTemplate.qml
Normal file
120
tests/auto/qml/qmldesigner/data/merging/SwitchTemplate.qml
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
import QtQuick 2.10
|
||||||
|
import QtQuick.Templates 2.1 as T
|
||||||
|
import TemplateMerging 1.0
|
||||||
|
|
||||||
|
T.Switch {
|
||||||
|
id: control
|
||||||
|
|
||||||
|
implicitWidth: background.implicitWidth
|
||||||
|
implicitHeight: background.implicitHeight
|
||||||
|
|
||||||
|
text: "test"
|
||||||
|
|
||||||
|
background: Item {
|
||||||
|
implicitWidth: switchBackground.width
|
||||||
|
implicitHeight: switchBackground.height
|
||||||
|
Rectangle {
|
||||||
|
id: switchBackground
|
||||||
|
color: "#ef1d1d"
|
||||||
|
border.color: "#808080"
|
||||||
|
width: 12 * 6.0
|
||||||
|
height: 12 * 3.8
|
||||||
|
anchors.fill: parent // has to be preserved
|
||||||
|
Text {
|
||||||
|
id: switchBackgroundText
|
||||||
|
anchors.right: parent.right // does have to be preserved -- how to handle this? - anchors preference from style if not "root"?
|
||||||
|
|
||||||
|
anchors.verticalCenter: parent.verticalCenter // does have to be preserved -- how to handle this? - anchors preference from style if not "root"?
|
||||||
|
text: control.text // has to be preserved
|
||||||
|
anchors.rightMargin: 12 * 5
|
||||||
|
}
|
||||||
|
Rectangle {
|
||||||
|
id: nonSenseRectangle
|
||||||
|
width: 5 * 12.0
|
||||||
|
height: 6 * 49.0
|
||||||
|
color: "#ff0000"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
leftPadding: 4
|
||||||
|
|
||||||
|
contentItem: Item { //designer want to edit the label as part of background
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
indicator: Rectangle {
|
||||||
|
id: switchIndicator
|
||||||
|
width: 58
|
||||||
|
height: 31
|
||||||
|
x: control.leftPadding // has to be preserved
|
||||||
|
color: "#e9e9e9"
|
||||||
|
anchors.verticalCenter: parent.verticalCenter // has to be preserved
|
||||||
|
radius: 16
|
||||||
|
border.color: "#dddddd"
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: switchHandle //id is required for states
|
||||||
|
|
||||||
|
width: 31
|
||||||
|
height: 31
|
||||||
|
radius: 16
|
||||||
|
color: "#e9e9e9"
|
||||||
|
border.color: "#808080"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
states: [
|
||||||
|
State {
|
||||||
|
name: "off"
|
||||||
|
when: !control.checked && !control.down
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "on"
|
||||||
|
when: control.checked && !control.down
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: switchIndicator
|
||||||
|
color: "#1713de"
|
||||||
|
border.color: "#1713de"
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: switchHandle
|
||||||
|
x: parent.width - width
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "off_down"
|
||||||
|
when: !control.checked && control.down
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: switchIndicator
|
||||||
|
color: "#e9e9e9"
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: switchHandle
|
||||||
|
color: "#d2d2d2"
|
||||||
|
border.color: "#d2d2d2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "on_down"
|
||||||
|
when: control.checked && control.down
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: switchHandle
|
||||||
|
x: parent.width - width
|
||||||
|
color: "#e9e9e9"
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: switchIndicator
|
||||||
|
color: "#030381"
|
||||||
|
border.color: "#030381"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Reference in New Issue
Block a user