Merge remote-tracking branch 'origin/qds-1.50' into qds-1.59

Change-Id: Id492d324031d4d5fb919eca80ffae4baa50f247f
This commit is contained in:
Tim Jenssen
2020-05-05 21:01:17 +02:00
41 changed files with 925 additions and 276 deletions

View File

@@ -176,7 +176,7 @@
\list 1
\li Select \uicontrol File > \uicontrol {New File or Project} >
\uicontrol {Application (Qt Quick)} >
\uicontrol {Application (Qt for MCU)} >
\uicontrol {MCU Support Application} > \uicontrol Choose.
\li Follow the instructions of the wizard to create the project.
\li Select \uicontrol Projects > \uicontrol {Build & Run}, and then

View File

@@ -83,6 +83,10 @@ def get_arguments():
action='store_true', default=(not common.is_windows_platform()))
parser.add_argument('--no-docs', help='Skip documentation generation',
action='store_true', default=False)
parser.add_argument('--no-dmg', help='Skip disk image creation (macOS)',
action='store_true', default=False)
parser.add_argument('--no-zip', help='Skip creation of 7zip files for install and developer package',
action='store_true', default=False)
return parser.parse_args()
def build_qtcreator(args, paths):
@@ -124,8 +128,7 @@ def build_qtcreator(args, paths):
'-DPYTHON_INCLUDE_DIR=' + os.path.join(args.python_path, 'include')]
# TODO this works around a CMake bug https://gitlab.kitware.com/cmake/cmake/issues/20119
if common.is_linux_platform():
cmake_args += ['-DBUILD_WITH_PCH=OFF']
cmake_args += ['-DBUILD_WITH_PCH=OFF']
ide_revision = common.get_commit_SHA(paths.src)
if ide_revision:
@@ -191,30 +194,32 @@ def deploy_qt(args, paths):
paths.build)
def package_qtcreator(args, paths):
common.check_print_call(['7z', 'a', '-mmt2', os.path.join(paths.result, 'qtcreator.7z'), '*'],
paths.install)
common.check_print_call(['7z', 'a', '-mmt2',
os.path.join(paths.result, 'qtcreator_dev.7z'), '*'],
paths.dev_install)
if common.is_windows_platform():
if not args.no_zip:
common.check_print_call(['7z', 'a', '-mmt2', os.path.join(paths.result, 'qtcreator.7z'), '*'],
paths.install)
common.check_print_call(['7z', 'a', '-mmt2',
os.path.join(paths.result, 'wininterrupt.7z'), '*'],
paths.wininterrupt_install)
if not args.no_cdb:
os.path.join(paths.result, 'qtcreator_dev.7z'), '*'],
paths.dev_install)
if common.is_windows_platform():
common.check_print_call(['7z', 'a', '-mmt2',
os.path.join(paths.result, 'qtcreatorcdbext.7z'), '*'],
paths.qtcreatorcdbext_install)
os.path.join(paths.result, 'wininterrupt.7z'), '*'],
paths.wininterrupt_install)
if not args.no_cdb:
common.check_print_call(['7z', 'a', '-mmt2',
os.path.join(paths.result, 'qtcreatorcdbext.7z'), '*'],
paths.qtcreatorcdbext_install)
if common.is_mac_platform():
if args.keychain_unlock_script:
common.check_print_call([args.keychain_unlock_script], paths.install)
common.check_print_call(['python', '-u',
os.path.join(paths.src, 'scripts', 'makedmg.py'),
'qt-creator.dmg',
'Qt Creator',
paths.src,
paths.install],
paths.result)
if not args.no_dmg:
common.check_print_call(['python', '-u',
os.path.join(paths.src, 'scripts', 'makedmg.py'),
'qt-creator.dmg',
'Qt Creator',
paths.src,
paths.install],
paths.result)
def get_paths(args):
Paths = collections.namedtuple('Paths',

130
scripts/build_plugin.py Executable file
View File

@@ -0,0 +1,130 @@
#!/usr/bin/env python
#############################################################################
##
## Copyright (C) 2020 The Qt Company Ltd.
## Contact: https://www.qt.io/licensing/
##
## This file is part of the release tools of the Qt Toolkit.
##
## $QT_BEGIN_LICENSE:GPL-EXCEPT$
## 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.
##
## $QT_END_LICENSE$
##
#############################################################################
# import the print function which is used in python 3.x
from __future__ import print_function
import argparse
import collections
import os
import common
def get_arguments():
parser = argparse.ArgumentParser(description='Build Qt Creator for packaging')
parser.add_argument('--name', help='Name to use for build results', required=True)
parser.add_argument('--src', help='Path to sources', required=True)
parser.add_argument('--build', help='Path that should be used for building', required=True)
parser.add_argument('--qt-path', help='Path to Qt', required=True)
parser.add_argument('--qtc-path',
help='Path to Qt Creator installation including development package',
required=True)
parser.add_argument('--output-path', help='Output path for resulting 7zip files')
parser.add_argument('--add-path', help='Adds a CMAKE_PREFIX_PATH to the build',
action='append', dest='prefix_paths', default=[])
parser.add_argument('--deploy', help='Installs the "Dependencies" component of the plugin.',
action='store_true', default=False)
parser.add_argument('--debug', help='Enable debug builds', action='store_true', default=False)
return parser.parse_args()
def build(args, paths):
if not os.path.exists(paths.build):
os.makedirs(paths.build)
if not os.path.exists(paths.result):
os.makedirs(paths.result)
prefix_paths = [paths.qt, paths.qt_creator] + [os.path.abspath(fp) for fp in args.prefix_paths]
build_type = 'Debug' if args.debug else 'Release'
cmake_args = ['cmake',
'-DCMAKE_PREFIX_PATH=' + ';'.join(prefix_paths),
'-DCMAKE_BUILD_TYPE=' + build_type,
'-DCMAKE_INSTALL_PREFIX=' + paths.install,
'-G', 'Ninja']
# force MSVC on Windows, because it looks for GCC in the PATH first,
# even if MSVC is first mentioned in the PATH...
# TODO would be nicer if we only did this if cl.exe is indeed first in the PATH
if common.is_windows_platform():
cmake_args += ['-DCMAKE_C_COMPILER=cl',
'-DCMAKE_CXX_COMPILER=cl']
# TODO this works around a CMake bug https://gitlab.kitware.com/cmake/cmake/issues/20119
cmake_args += ['-DBUILD_WITH_PCH=OFF']
ide_revision = common.get_commit_SHA(paths.src)
if ide_revision:
cmake_args += ['-DQTC_PLUGIN_REVISION=' + ide_revision]
with open(os.path.join(paths.result, args.name + '.7z.git_sha'), 'w') as f:
f.write(ide_revision)
common.check_print_call(cmake_args + [paths.src], paths.build)
common.check_print_call(['cmake', '--build', '.'], paths.build)
common.check_print_call(['cmake', '--install', '.', '--prefix', paths.install, '--strip'],
paths.build)
if args.deploy:
common.check_print_call(['cmake', '--install', '.', '--prefix', paths.install,
'--component', 'Dependencies'],
paths.build)
common.check_print_call(['cmake', '--install', '.', '--prefix', paths.dev_install,
'--component', 'Devel'],
paths.build)
def package(args, paths):
if not os.path.exists(paths.result):
os.makedirs(paths.result)
common.check_print_call(['7z', 'a', '-mmt2', os.path.join(paths.result, args.name + '.7z'), '*'],
paths.install)
if os.path.exists(paths.dev_install): # some plugins might not provide anything in Devel
common.check_print_call(['7z', 'a', '-mmt2',
os.path.join(paths.result, args.name + '_dev.7z'), '*'],
paths.dev_install)
def get_paths(args):
Paths = collections.namedtuple('Paths',
['qt', 'src', 'build', 'qt_creator',
'install', 'dev_install', 'result'])
build_path = os.path.abspath(args.build)
install_path = os.path.join(build_path, 'install')
result_path = os.path.abspath(args.output_path) if args.output_path else build_path
return Paths(qt=os.path.abspath(args.qt_path),
src=os.path.abspath(args.src),
build=os.path.join(build_path, 'build'),
qt_creator=os.path.abspath(args.qtc_path),
install=os.path.join(install_path, args.name),
dev_install=os.path.join(install_path, args.name + '-dev'),
result=result_path)
def main():
args = get_arguments()
paths = get_paths(args)
build(args, paths)
package(args, paths)
if __name__ == '__main__':
main()

View File

@@ -26,6 +26,8 @@
import HelperWidgets 2.0
import QtQuick 2.1
import QtQuick.Layouts 1.1
import StudioTheme 1.0 as StudioTheme
Section {
id: section
caption: qsTr("Animation")
@@ -33,6 +35,7 @@ Section {
anchors.right: parent.right
property bool showDuration: true
property bool showEasingCurve: false
SectionLayout {
Label {
@@ -100,5 +103,22 @@ Section {
text: backendValues.alwaysRunToEnd.valueToString
backendValue: backendValues.alwaysRunToEnd
}
Label {
visible: section.showEasingCurve
text: qsTr("Easing Curve")
tooltip: qsTr("Define custom easing curve")
}
BoolButtonRowButton {
visible: section.showEasingCurve
buttonIcon: StudioTheme.Constants.curveDesigner
EasingCurveEditor {
id: easingCurveEditor
modelNodeBackendProperty: modelNodeBackend
}
onClicked: easingCurveEditor.runDialog()
}
}
}

View File

@@ -57,6 +57,7 @@ Column {
}
AnimationSection {
showEasingCurve: true
}
}

View File

@@ -79,6 +79,7 @@ Column {
}
AnimationSection {
showEasingCurve: true
}
}

View File

@@ -35,6 +35,7 @@ Column {
}
AnimationSection {
showEasingCurve: true
}
}

View File

@@ -163,4 +163,9 @@ StudioControls.ComboBox {
colorLogic.invalidate()
comboBox.__isCompleted = true
}
Connections {
target: modelNodeBackend
onSelectionToBeChanged: comboBox.popup.close()
}
}

View File

@@ -193,7 +193,7 @@ Section {
Layout.fillWidth: true
backendValue: getBackendValue("styleName")
model: styleNamesForFamily(fontComboBox.familyName)
useString: true
valueType: ComboBox.String
}
Label {

View File

@@ -36,9 +36,11 @@ ButtonRow {
property alias checked: myAbstractButton.checked
signal onCheckedChanged()
signal clicked
AbstractButton {
id: myAbstractButton
onCheckedChanged: myButtonRow.onCheckedChanged()
onClicked: myButtonRow.clicked()
}
}

View File

@@ -48,67 +48,73 @@ QtObject {
readonly property string adsClose: "\u0029"
readonly property string adsDetach: "\u002A"
readonly property string adsDropDown: "\u002B"
readonly property string alignBottom: "\u002C"
readonly property string alignCenterHorizontal: "\u002D"
readonly property string alignCenterVertical: "\u002E"
readonly property string alignLeft: "\u002F"
readonly property string alignRight: "\u0030"
readonly property string alignTo: "\u0031"
readonly property string alignTop: "\u0032"
readonly property string anchorBaseline: "\u0033"
readonly property string anchorBottom: "\u0034"
readonly property string anchorFill: "\u0035"
readonly property string anchorLeft: "\u0036"
readonly property string anchorRight: "\u0037"
readonly property string anchorTop: "\u0038"
readonly property string annotationBubble: "\u0039"
readonly property string annotationDecal: "\u003A"
readonly property string centerHorizontal: "\u003B"
readonly property string centerVertical: "\u003C"
readonly property string closeCross: "\u003D"
readonly property string decisionNode: "\u003E"
readonly property string deleteColumn: "\u003F"
readonly property string deleteRow: "\u0040"
readonly property string deleteTable: "\u0041"
readonly property string detach: "\u0042"
readonly property string distributeBottom: "\u0043"
readonly property string distributeCenterHorizontal: "\u0044"
readonly property string distributeCenterVertical: "\u0045"
readonly property string distributeLeft: "\u0046"
readonly property string distributeOriginBottomRight: "\u0047"
readonly property string distributeOriginCenter: "\u0048"
readonly property string distributeOriginNone: "\u0049"
readonly property string distributeOriginTopLeft: "\u004A"
readonly property string distributeRight: "\u004B"
readonly property string distributeSpacingHorizontal: "\u004C"
readonly property string distributeSpacingVertical: "\u004D"
readonly property string distributeTop: "\u004E"
readonly property string edit: "\u004F"
readonly property string fontStyleBold: "\u0050"
readonly property string fontStyleItalic: "\u0051"
readonly property string fontStyleStrikethrough: "\u0052"
readonly property string fontStyleUnderline: "\u0053"
readonly property string mergeCells: "\u0054"
readonly property string redo: "\u0055"
readonly property string splitColumns: "\u0056"
readonly property string splitRows: "\u0057"
readonly property string startNode: "\u0058"
readonly property string testIcon: "\u0059"
readonly property string textAlignBottom: "\u005A"
readonly property string textAlignCenter: "\u005B"
readonly property string textAlignLeft: "\u005C"
readonly property string textAlignMiddle: "\u005D"
readonly property string textAlignRight: "\u005E"
readonly property string textAlignTop: "\u005F"
readonly property string textBulletList: "\u0060"
readonly property string textFullJustification: "\u0061"
readonly property string textNumberedList: "\u0062"
readonly property string tickIcon: "\u0063"
readonly property string triState: "\u0064"
readonly property string undo: "\u0065"
readonly property string upDownIcon: "\u0066"
readonly property string upDownSquare2: "\u0067"
readonly property string wildcard: "\u0068"
readonly property string aliasAnimated: "\u002C"
readonly property string aliasProperty: "\u002D"
readonly property string alignBottom: "\u002E"
readonly property string alignCenterHorizontal: "\u002F"
readonly property string alignCenterVertical: "\u0030"
readonly property string alignLeft: "\u0031"
readonly property string alignRight: "\u0032"
readonly property string alignTo: "\u0033"
readonly property string alignTop: "\u0034"
readonly property string anchorBaseline: "\u0035"
readonly property string anchorBottom: "\u0036"
readonly property string anchorFill: "\u0037"
readonly property string anchorLeft: "\u0038"
readonly property string anchorRight: "\u0039"
readonly property string anchorTop: "\u003A"
readonly property string animatedProperty: "\u003B"
readonly property string annotationBubble: "\u003C"
readonly property string annotationDecal: "\u003D"
readonly property string assign: "\u003E"
readonly property string centerHorizontal: "\u003F"
readonly property string centerVertical: "\u0040"
readonly property string closeCross: "\u0041"
readonly property string curveDesigner: "\u0042"
readonly property string curveEditor: "\u0043"
readonly property string decisionNode: "\u0044"
readonly property string deleteColumn: "\u0045"
readonly property string deleteRow: "\u0046"
readonly property string deleteTable: "\u0047"
readonly property string detach: "\u0048"
readonly property string distributeBottom: "\u0049"
readonly property string distributeCenterHorizontal: "\u004A"
readonly property string distributeCenterVertical: "\u004B"
readonly property string distributeLeft: "\u004C"
readonly property string distributeOriginBottomRight: "\u004D"
readonly property string distributeOriginCenter: "\u004E"
readonly property string distributeOriginNone: "\u004F"
readonly property string distributeOriginTopLeft: "\u0050"
readonly property string distributeRight: "\u0051"
readonly property string distributeSpacingHorizontal: "\u0052"
readonly property string distributeSpacingVertical: "\u0053"
readonly property string distributeTop: "\u0054"
readonly property string edit: "\u0055"
readonly property string fontStyleBold: "\u0056"
readonly property string fontStyleItalic: "\u0057"
readonly property string fontStyleStrikethrough: "\u0058"
readonly property string fontStyleUnderline: "\u0059"
readonly property string mergeCells: "\u005A"
readonly property string redo: "\u005B"
readonly property string splitColumns: "\u005C"
readonly property string splitRows: "\u005D"
readonly property string startNode: "\u005E"
readonly property string testIcon: "\u005F"
readonly property string textAlignBottom: "\u0060"
readonly property string textAlignCenter: "\u0061"
readonly property string textAlignLeft: "\u0062"
readonly property string textAlignMiddle: "\u0063"
readonly property string textAlignRight: "\u0064"
readonly property string textAlignTop: "\u0065"
readonly property string textBulletList: "\u0066"
readonly property string textFullJustification: "\u0067"
readonly property string textNumberedList: "\u0068"
readonly property string tickIcon: "\u0069"
readonly property string triState: "\u006A"
readonly property string undo: "\u006B"
readonly property string upDownIcon: "\u006C"
readonly property string upDownSquare2: "\u006D"
readonly property string wildcard: "\u006E"
readonly property font iconFont: Qt.font({
"family": controlIcons.name,

View File

@@ -776,7 +776,13 @@ static QString fromLocalEncoding(const QByteArray &data)
static QString getProcessOutput(const QString &command, const QString &input)
{
QProcess proc;
#if QT_VERSION >= QT_VERSION_CHECK(5,15,0)
QStringList arguments = QProcess::splitCommand(command);
QString executable = arguments.takeFirst();
proc.start(executable, arguments);
#else
proc.start(command);
#endif
proc.waitForStarted();
proc.write(toLocalEncoding(input));
proc.closeWriteChannel();

View File

@@ -39,6 +39,7 @@ const char qmlPreviewCategory[] = "QmlPreview";
const char editCategory[] = "Edit";
const char anchorsCategory[] = "Anchors";
const char positionCategory[] = "Position";
const char groupCategory[] = "Group";
const char layoutCategory[] = "Layout";
const char flowCategory[] = "Flow";
const char flowEffectCategory[] = "FlowEffect";
@@ -78,6 +79,7 @@ const char addTabBarToStackedContainerCommandId[] = "AddTabBarToStackedContainer
const char increaseIndexOfStackedContainerCommandId[] = "IncreaseIndexOfStackedContainer";
const char decreaseIndexOfStackedContainerCommandId[] = "DecreaseIndexOfStackedContainer";
const char flowAssignEffectCommandId[] = "AssignFlowEffect";
const char addToGroupItemCommandId[] = "AddToGroupItem";
const char selectionCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Selection");
const char flowConnectionCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Connect");
@@ -85,6 +87,7 @@ const char stackCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMen
const char editCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Edit");
const char anchorsCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Anchors");
const char positionCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Position");
const char groupCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Group");
const char layoutCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Layout");
const char flowCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Flow");
const char flowEffectCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Flow Effects");
@@ -130,6 +133,8 @@ const char createFlowActionAreaDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerCon
const char setFlowStartDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Set Flow Start");
const char removeLayoutDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Remove Layout");
const char addToGroupItemDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Group in GroupItem");
const char addItemToStackedContainerDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Add Item");
const char addTabBarToStackedContainerDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Add Tab Bar");
const char increaseIndexToStackedContainerDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Increase Index");
@@ -169,6 +174,7 @@ const int priorityStackCategory = 180;
const int priorityEditCategory = 160;
const int priorityAnchorsCategory = 140;
const int priorityFlowCategory = 240;
const int priorityGroupCategory = 140;
const int priorityPositionCategory = 130;
const int priorityLayoutCategory = 120;
const int priorityStackedContainerCategory = priorityLayoutCategory;

View File

@@ -648,6 +648,12 @@ bool positionOptionVisible(const SelectionContext &context)
|| isPositioner(context);
}
bool studioComponentsAvailable(const SelectionContext &context)
{
const Import import = Import::createLibraryImport("QtQuick.Studio.Components", "1.0");
return context.view()->model()->isImportPossible(import, true, true);
}
bool singleSelectedAndUiFile(const SelectionContext &context)
{
if (!singleSelection(context))
@@ -859,6 +865,13 @@ void DesignerActionManager::createDefaultDesignerActions()
priorityLayoutCategory,
&layoutOptionVisible));
addDesignerAction(new ActionGroup(
groupCategoryDisplayName,
groupCategory,
priorityGroupCategory,
&positionOptionVisible,
&studioComponentsAvailable));
addDesignerAction(new ActionGroup(
flowCategoryDisplayName,
flowCategory,
@@ -994,6 +1007,18 @@ void DesignerActionManager::createDefaultDesignerActions()
&isLayout,
&isLayout));
addDesignerAction(new ModelNodeContextMenuAction(
addToGroupItemCommandId,
addToGroupItemDisplayName,
{},
groupCategory,
QKeySequence(),
110,
&addToGroupItem,
&selectionCanBeLayouted,
&selectionCanBeLayouted));
addDesignerAction(new ModelNodeFormEditorAction(
addItemToStackedContainerCommandId,
addItemToStackedContainerDisplayName,
@@ -1212,6 +1237,10 @@ void DesignerActionManager::addTransitionEffectAction(const TypeName &typeName)
DesignerActionToolBar::DesignerActionToolBar(QWidget *parentWidget) : Utils::StyledBar(parentWidget),
m_toolBar(new QToolBar("ActionToolBar", this))
{
QWidget* empty = new QWidget();
empty->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Preferred);
m_toolBar->addWidget(empty);
m_toolBar->setContentsMargins(0, 0, 0, 0);
m_toolBar->setFloatable(true);
m_toolBar->setMovable(true);

View File

@@ -25,6 +25,8 @@
#include "designeractionmanagerview.h"
#include <customnotifications.h>
#include <selectioncontext.h>
#include <actioninterface.h>
#include <variantproperty.h>
@@ -53,7 +55,7 @@ void DesignerActionManagerView::modelAboutToBeDetached(Model *model)
void DesignerActionManagerView::nodeCreated(const ModelNode &)
{
setupContext(SelectionContext::UpdateMode::Fast);
setupContext(SelectionContext::UpdateMode::NodeCreated);
}
void DesignerActionManagerView::nodeRemoved(const ModelNode &, const NodeAbstractProperty &, AbstractView::PropertyChangeFlags)
@@ -63,17 +65,17 @@ void DesignerActionManagerView::nodeRemoved(const ModelNode &, const NodeAbstrac
void DesignerActionManagerView::nodeAboutToBeReparented(const ModelNode &, const NodeAbstractProperty &, const NodeAbstractProperty &, AbstractView::PropertyChangeFlags)
{
setupContext(SelectionContext::UpdateMode::Fast);
setupContext(SelectionContext::UpdateMode::NodeHierachy);
}
void DesignerActionManagerView::nodeReparented(const ModelNode &, const NodeAbstractProperty &, const NodeAbstractProperty &, AbstractView::PropertyChangeFlags)
{
setupContext(SelectionContext::UpdateMode::Fast);
setupContext(SelectionContext::UpdateMode::NodeHierachy);
}
void DesignerActionManagerView::propertiesRemoved(const QList<AbstractProperty> &)
{
setupContext(SelectionContext::UpdateMode::Fast);
setupContext(SelectionContext::UpdateMode::Properties);
}
void DesignerActionManagerView::rootNodeTypeChanged(const QString &, int, int)
@@ -112,7 +114,7 @@ void DesignerActionManagerView::selectedNodesChanged(const QList<ModelNode> &sel
void DesignerActionManagerView::nodeOrderChanged(const NodeListProperty &, const ModelNode &, int)
{
setupContext(SelectionContext::UpdateMode::Fast);
setupContext(SelectionContext::UpdateMode::NodeHierachy);
}
void DesignerActionManagerView::importsChanged(const QList<Import> &, const QList<Import> &)
@@ -122,27 +124,38 @@ void DesignerActionManagerView::importsChanged(const QList<Import> &, const QLis
void DesignerActionManagerView::signalHandlerPropertiesChanged(const QVector<SignalHandlerProperty> &, AbstractView::PropertyChangeFlags)
{
setupContext(SelectionContext::UpdateMode::Fast);
setupContext(SelectionContext::UpdateMode::Properties);
}
void DesignerActionManagerView::variantPropertiesChanged(const QList<VariantProperty> &, AbstractView::PropertyChangeFlags propertyChangeFlag)
{
if (propertyChangeFlag == AbstractView::PropertiesAdded)
setupContext(SelectionContext::UpdateMode::Fast);
setupContext(SelectionContext::UpdateMode::Properties);
else if (hasSingleSelectedModelNode())
setupContext(SelectionContext::UpdateMode::Fast);
setupContext(SelectionContext::UpdateMode::Properties);
}
void DesignerActionManagerView::bindingPropertiesChanged(const QList<BindingProperty> &, AbstractView::PropertyChangeFlags propertyChangeFlag)
{
if (propertyChangeFlag == AbstractView::PropertiesAdded)
setupContext(SelectionContext::UpdateMode::Fast);
setupContext(SelectionContext::UpdateMode::Properties);
}
void DesignerActionManagerView::instancePropertyChanged(const QList<QPair<ModelNode, PropertyName> > &)
{
if (hasSingleSelectedModelNode())
setupContext(SelectionContext::UpdateMode::Fast);
setupContext(SelectionContext::UpdateMode::Properties);
}
void DesignerActionManagerView::customNotification(const AbstractView * /*view*/,
const QString &identifier,
const QList<ModelNode> & /* nodeList */,
const QList<QVariant> & /*data */)
{
if (identifier == StartRewriterAmend)
m_isInRewriterTransaction = true;
else if (identifier == EndRewriterAmend)
m_isInRewriterTransaction = false;
}
DesignerActionManager &DesignerActionManagerView::designerActionManager()

View File

@@ -71,6 +71,10 @@ public:
void emitSelectionChanged();
void setupContext(SelectionContext::UpdateMode updateMode = SelectionContext::UpdateMode::Normal);
void customNotification(const AbstractView *,
const QString &identifier,
const QList<ModelNode> &,
const QList<QVariant> &) override;
signals:
void selectionChanged(bool itemsSelected, bool rootItemIsSelected);

View File

@@ -167,7 +167,6 @@ void LayoutInGridLayout::doIt()
const TypeName layoutType = "QtQuick.Layouts.GridLayout";
if (!m_selectionContext.view()
|| !m_selectionContext.hasSingleSelectedModelNode()
|| !m_selectionContext.view()->model()->hasNodeMetaInfo(layoutType))
return;

View File

@@ -457,7 +457,6 @@ static void layoutHelperFunction(const SelectionContext &selectionContext,
const LessThan &lessThan)
{
if (!selectionContext.view()
|| !selectionContext.hasSingleSelectedModelNode()
|| !selectionContext.view()->model()->hasNodeMetaInfo(layoutType))
return;
@@ -1120,6 +1119,88 @@ void setFlowStartItem(const SelectionContext &selectionContext)
});
}
bool static hasStudioComponentsImport(const SelectionContext &context)
{
if (context.view() && context.view()->model()) {
Import import = Import::createLibraryImport("QtQuick.Studio.Components", "1.0");
return context.view()->model()->hasImport(import, true, true);
}
return false;
}
static inline void setAdjustedPos(const QmlDesigner::ModelNode &modelNode)
{
if (modelNode.hasParentProperty()) {
ModelNode parentNode = modelNode.parentProperty().parentModelNode();
const QPointF instancePos = QmlItemNode(modelNode).instancePosition();
const int x = instancePos.x() - parentNode.variantProperty("x").value().toInt();
const int y = instancePos.y() - parentNode.variantProperty("y").value().toInt();
modelNode.variantProperty("x").setValue(x);
modelNode.variantProperty("y").setValue(y);
}
}
void reparentToNodeAndAdjustPosition(const ModelNode &parentModelNode,
const QList<ModelNode> &modelNodeList)
{
for (ModelNode modelNode : modelNodeList) {
reparentTo(modelNode, parentModelNode);
setAdjustedPos(modelNode);
for (const VariantProperty &variantProperty : modelNode.variantProperties()) {
if (variantProperty.name().contains("anchors."))
modelNode.removeProperty(variantProperty.name());
}
for (const BindingProperty &bindingProperty : modelNode.bindingProperties()) {
if (bindingProperty.name().contains("anchors."))
modelNode.removeProperty(bindingProperty.name());
}
}
}
void addToGroupItem(const SelectionContext &selectionContext)
{
const TypeName typeName = "QtQuick.Studio.Components.GroupItem";
try {
if (!hasStudioComponentsImport(selectionContext)) {
Import studioImport = Import::createLibraryImport("QtQuick.Studio.Components", "1.0");
selectionContext.view()-> model()->changeImports({studioImport}, {});
}
if (!selectionContext.view())
return;
if (QmlItemNode::isValidQmlItemNode(selectionContext.firstSelectedModelNode())) {
const QmlItemNode qmlItemNode = QmlItemNode(selectionContext.firstSelectedModelNode());
if (qmlItemNode.hasInstanceParentItem()) {
ModelNode groupNode;
selectionContext.view()->executeInTransaction("DesignerActionManager|addToGroupItem1",[=, &groupNode](){
QmlItemNode parentNode = qmlItemNode.instanceParentItem();
NodeMetaInfo metaInfo = selectionContext.view()->model()->metaInfo(typeName);
groupNode = selectionContext.view()->createModelNode(typeName, metaInfo.majorVersion(), metaInfo.minorVersion());
reparentTo(groupNode, parentNode);
});
selectionContext.view()->executeInTransaction("DesignerActionManager|addToGroupItem2",[=](){
QList<ModelNode> selectedNodes = selectionContext.selectedModelNodes();
setUpperLeftPostionToNode(groupNode, selectedNodes);
reparentToNodeAndAdjustPosition(groupNode, selectedNodes);
});
}
}
} catch (RewritingException &e) {
e.showException();
}
}
} // namespace Mode
} //QmlDesigner

View File

@@ -78,6 +78,7 @@ void createFlowActionArea(const SelectionContext &selectionContext);
void addTransition(const SelectionContext &selectionState);
void addFlowEffect(const SelectionContext &selectionState, const TypeName &typeName);
void setFlowStartItem(const SelectionContext &selectionContext);
void addToGroupItem(const SelectionContext &selectionContext);
} // namespace ModelNodeOperationso
} //QmlDesigner

View File

@@ -124,12 +124,17 @@ bool SelectionContext::isValid() const
bool SelectionContext::fastUpdate() const
{
return m_updateMode == UpdateMode::Fast;
return m_updateReason != UpdateMode::Normal;
}
void SelectionContext::setUpdateMode(UpdateMode mode)
{
m_updateMode = mode;
m_updateReason = mode;
}
SelectionContext::UpdateMode SelectionContext::updateReason() const
{
return m_updateReason;
}
} //QmlDesigner

View File

@@ -35,7 +35,14 @@ namespace QmlDesigner {
class QMLDESIGNERCORE_EXPORT SelectionContext {
public:
enum class UpdateMode {Normal, Fast};
enum class UpdateMode {
Normal,
Fast,
Properties,
NodeCreated,
NodeHierachy,
Selection
};
SelectionContext();
SelectionContext(AbstractView *view);
@@ -68,13 +75,15 @@ public:
bool fastUpdate() const;
void setUpdateMode(UpdateMode mode);
UpdateMode updateReason() const;
private:
QPointer<AbstractView> m_view;
ModelNode m_targetNode;
QPointF m_scenePosition;
bool m_showSelectionTools = false;
bool m_toggled = false;
UpdateMode m_updateMode = UpdateMode::Normal;
UpdateMode m_updateReason = UpdateMode::Normal;
};
} //QmlDesigner

View File

@@ -57,6 +57,8 @@ public:
adsClose,
adsDetach,
adsDropDown,
aliasAnimated,
aliasProperty,
alignBottom,
alignCenterHorizontal,
alignCenterVertical,
@@ -64,6 +66,7 @@ public:
alignRight,
alignTo,
alignTop,
assign,
anchorBaseline,
anchorBottom,
anchorFill,
@@ -74,6 +77,7 @@ public:
annotationDecal,
centerHorizontal,
centerVertical,
curveEditor,
closeCross,
decisionNode,
deleteColumn,

View File

@@ -443,6 +443,8 @@ void FormEditorItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *,
|| painterTransform.isRotating())
painter->setRenderHint(QPainter::SmoothPixmapTransform, true);
painter->setClipRegion(boundingRect().toRect());
if (m_blurContent)
painter->drawPixmap(m_paintedBoundingRect.topLeft(), qmlItemNode().instanceBlurredRenderPixmap());
else
@@ -452,6 +454,7 @@ void FormEditorItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *,
}
}
painter->setClipping(false);
if (!qmlItemNode().isRootModelNode())
paintBoundingRect(painter);
@@ -790,10 +793,10 @@ QPointF FormEditorTransitionItem::instancePosition() const
static bool verticalOverlap(const QRectF &from, const QRectF &to)
{
if (from.top() < to.bottom() && (from.top() + from.height()) > to.top())
if (from.top() < to.bottom() && from.bottom() > to.top())
return true;
if (to.top() < from.bottom() && (to.top() + to.height()) > from.top())
if (to.top() < from.bottom() && to.bottom() > from.top())
return true;
return false;
@@ -802,25 +805,77 @@ static bool verticalOverlap(const QRectF &from, const QRectF &to)
static bool horizontalOverlap(const QRectF &from, const QRectF &to)
{
if (from.left() < to.right() && (from.left() + from.width()) > to.left())
if (from.left() < to.right() && from.right() > to.left())
return true;
if (to.left() < from.right() && (to.left() + to.width()) > from.left())
if (to.left() < from.right() && to.right() > from.left())
return true;
return false;
}
static void drawArrow(QPainter *painter,
const QLineF &line,
int arrowLength,
int arrowWidth)
{
const QPointF peakP(0, 0);
const QPointF leftP(-arrowLength, -arrowWidth * 0.5);
const QPointF rightP(-arrowLength, arrowWidth * 0.5);
painter->save();
painter->translate(line.p2());
painter->rotate(-line.angle());
painter->drawLine(leftP, peakP);
painter->drawLine(rightP, peakP);
painter->restore();
}
static void drawRoundedCorner(QPainter *painter,
const QPointF &s,
const QPointF &m,
const QPointF &e,
int radius)
{
const QVector2D sm(m - s);
const QVector2D me(e - m);
const float smLength = sm.length();
const float meLength = me.length();
const int actualRadius = qMin(radius, static_cast<int>(qMin(smLength, meLength)));
const QVector2D smNorm = sm.normalized();
const QVector2D meNorm = me.normalized();
const QPointF arcStartP = s + (smNorm * (smLength - actualRadius)).toPointF();
QRectF rect(m, QSizeF(actualRadius * 2, actualRadius * 2));
painter->drawLine(s, arcStartP);
if ((smNorm.y() < 0 && meNorm.x() > 0) || (smNorm.x() < 0 && meNorm.y() > 0)) {
rect.moveTopLeft(m);
painter->drawArc(rect, 90 * 16, 90 * 16);
} else if ((smNorm.y() > 0 && meNorm.x() > 0) || (smNorm.x() < 0 && meNorm.y() < 0)) {
rect.moveBottomLeft(m);
painter->drawArc(rect, 180 * 16, 90 * 16);
} else if ((smNorm.x() > 0 && meNorm.y() > 0) || (smNorm.y() < 0 && meNorm.x() < 0)) {
rect.moveTopRight(m);
painter->drawArc(rect, 0 * 16, 90 * 16);
} else if ((smNorm.y() > 0 && meNorm.x() < 0) || (smNorm.x() > 0 && meNorm.y() < 0)) {
rect.moveBottomRight(m);
painter->drawArc(rect, 270 * 16, 90 * 16);
}
const QPointF arcEndP = e - (meNorm * (meLength - actualRadius)).toPointF();
painter->drawLine(arcEndP, e);
}
static void paintConnection(QPainter *painter,
const QRectF &from,
const QRectF &to,
qreal width,
qreal adjustedWidth,
const QColor &color,
bool dash,
int startOffset,
int endOffset,
int breakOffset)
const ConnectionStyle &style)
{
painter->save();
painter->setRenderHint(QPainter::Antialiasing);
@@ -829,23 +884,22 @@ static void paintConnection(QPainter *painter,
pen.setCosmetic(true);
pen.setJoinStyle(Qt::MiterJoin);
pen.setCapStyle(Qt::RoundCap);
pen.setColor(style.color);
pen.setColor(color);
if (dash)
if (style.dash)
pen.setStyle(Qt::DashLine);
else
pen.setStyle(Qt::SolidLine);
pen.setWidthF(width);
pen.setWidthF(style.width);
painter->setPen(pen);
//const bool forceVertical = false;
//const bool forceHorizontal = false;
const int padding = 2 * width + 2 * adjustedWidth;
const int padding = 2 * style.width + 2 * style.adjustedWidth;
const int arrowLength = 4 * adjustedWidth;
const int arrowWidth = 8 * adjustedWidth;
const int arrowLength = 4 * style.adjustedWidth;
const int arrowWidth = 8 * style.adjustedWidth;
const bool boolExitRight = from.right() < to.center().x();
const bool boolExitBottom = from.bottom() < to.center().y();
@@ -857,9 +911,10 @@ static void paintConnection(QPainter *painter,
horizontalFirst = false;
*/
const qreal middleFactor = breakOffset / 100.0;
const qreal middleFactor = style.breakOffset / 100.0;
QPointF startP;
QLineF lastSegment;
bool extraLine = false;
@@ -883,130 +938,97 @@ static void paintConnection(QPainter *painter,
}
if (horizontalFirst) {
const qreal startY = from.center().y() + startOffset;
qreal startX = from.x() - padding;
if (boolExitRight)
startX = from.right() + padding;
const qreal startX = boolExitRight ? from.right() + padding : from.x() - padding;
const qreal startY = from.center().y() + style.outOffset;
startP = QPointF(startX, startY);
qreal endY = to.top() - padding;
if (from.bottom() > to.y())
endY = to.bottom() + padding;
const qreal endY = (from.bottom() > to.y()) ? to.bottom() + padding : to.top() - padding;
if (!extraLine) {
const qreal endX = to.center().x() + endOffset;
const qreal endX = to.center().x() + style.inOffset;
const QPointF midP(endX, startY);
const QPointF endP(endX, endY);
painter->drawLine(startP, midP);
painter->drawLine(midP, endP);
if (style.radius == 0) {
painter->drawLine(startP, midP);
painter->drawLine(midP, endP);
} else {
drawRoundedCorner(painter, startP, midP, endP, style.radius);
}
int flip = 1;
if (midP.y() < endP.y())
flip = -1;
pen.setStyle(Qt::SolidLine);
painter->setPen(pen);
painter->drawLine(endP + flip * QPoint(arrowWidth / 2, arrowLength), endP);
painter->drawLine(endP + flip * QPoint(-arrowWidth / 2, arrowLength), endP);
lastSegment = QLineF(midP, endP);
} else {
qreal endX = to.left() - padding;
if (from.right() > to.x())
endX = to.right() + padding;
const qreal midX = startX * middleFactor + endX * (1-middleFactor);
const qreal endX = (from.right() > to.x()) ? to.right() + padding : to.left() - padding;
const qreal midX = startX * middleFactor + endX * (1 - middleFactor);
const QPointF midP(midX, startY);
const QPointF midP2(midX, to.center().y() + endOffset);
const QPointF endP(endX, to.center().y() + endOffset);
painter->drawLine(startP, midP);
painter->drawLine(midP, midP2);
painter->drawLine(midP2, endP);
const QPointF midP2(midX, to.center().y() + style.inOffset);
const QPointF endP(endX, to.center().y() + style.inOffset);
int flip = 1;
if (style.radius == 0) {
painter->drawLine(startP, midP);
painter->drawLine(midP, midP2);
painter->drawLine(midP2, endP);
} else {
const QLineF breakLine(midP, midP2);
drawRoundedCorner(painter, startP, midP, breakLine.center(), style.radius);
drawRoundedCorner(painter, breakLine.center(), midP2, endP, style.radius);
}
if (midP2.x() < endP.x())
flip = -1;
pen.setStyle(Qt::SolidLine);
painter->setPen(pen);
painter->drawLine(endP + flip * QPoint(arrowWidth / 2, arrowWidth / 2), endP);
painter->drawLine(endP + flip * QPoint(arrowLength, -arrowWidth / 2), endP);
lastSegment = QLineF(midP2, endP);
}
} else {
const qreal startX = from.center().x() + startOffset;
qreal startY = from.top() - padding;
if (boolExitBottom)
startY = from.bottom() + padding;
const qreal startX = from.center().x() + style.outOffset;
const qreal startY = boolExitBottom ? from.bottom() + padding : from.top() - padding;
startP = QPointF(startX, startY);
qreal endX = to.left() - padding;
if (from.right() > to.x())
endX = to.right() + padding;
const qreal endX = (from.right() > to.x()) ? to.right() + padding : to.left() - padding;
if (!extraLine) {
const qreal endY = to.center().y() + endOffset;
const qreal endY = to.center().y() + style.inOffset;
const QPointF midP(startX, endY);
const QPointF endP(endX, endY);
painter->drawLine(startP, midP);
painter->drawLine(midP, endP);
if (style.radius == 0) {
painter->drawLine(startP, midP);
painter->drawLine(midP, endP);
} else {
drawRoundedCorner(painter, startP, midP, endP, style.radius);
}
int flip = 1;
if (midP.x() < endP.x())
flip = -1;
pen.setStyle(Qt::SolidLine);
painter->setPen(pen);
painter->drawLine(endP + flip * QPoint(arrowWidth / 2, arrowWidth / 2), endP);
painter->drawLine(endP + flip * QPoint(arrowLength, -arrowWidth / 2), endP);
lastSegment = QLineF(midP, endP);
} else {
const qreal endY = (from.bottom() > to.y()) ? to.bottom() + padding : to.top() - padding;
qreal endY = to.top() - padding;
if (from.bottom() > to.y())
endY = to.bottom() + padding;
const qreal midY = startY * middleFactor + endY * (1-middleFactor);
const qreal midY = startY * middleFactor + endY * (1 - middleFactor);
const QPointF midP(startX, midY);
const QPointF midP2(to.center().x() + endOffset, midY);
const QPointF endP(to.center().x() + endOffset, endY);
const QPointF midP2(to.center().x() + style.inOffset, midY);
const QPointF endP(to.center().x() + style.inOffset, endY);
painter->drawLine(startP, midP);
painter->drawLine(midP, midP2);
painter->drawLine(midP2, endP);
if (style.radius == 0) {
painter->drawLine(startP, midP);
painter->drawLine(midP, midP2);
painter->drawLine(midP2, endP);
} else {
const QLineF breakLine(midP, midP2);
drawRoundedCorner(painter, startP, midP, breakLine.center(), style.radius);
drawRoundedCorner(painter, breakLine.center(), midP2, endP, style.radius);
}
int flip = 1;
if (midP2.y() < endP.y())
flip = -1;
pen.setStyle(Qt::SolidLine);
painter->setPen(pen);
painter->drawLine(endP + flip * QPoint(arrowWidth / 2, arrowLength), endP);
painter->drawLine(endP + flip * QPoint(-arrowWidth / 2, arrowLength), endP);
lastSegment = QLineF(midP2, endP);
}
}
pen.setWidthF(width);
pen.setWidthF(style.width);
pen.setStyle(Qt::SolidLine);
painter->setPen(pen);
drawArrow(painter, lastSegment, arrowLength, arrowWidth);
painter->setBrush(Qt::white);
painter->drawEllipse(startP, arrowLength / 3, arrowLength / 3);
painter->drawEllipse(startP, arrowLength / 3, arrowLength / 3);
painter->restore();
}
@@ -1063,57 +1085,67 @@ void FormEditorTransitionItem::paint(QPainter *painter, const QStyleOptionGraphi
toRect.translate(-pos());
fromRect.translate(-pos());
qreal width = 2;
ConnectionStyle style;
style.width = 2;
const qreal scaleFactor = viewportTransform().m11();
if (qmlItemNode().modelNode().hasAuxiliaryData("width"))
width = qmlItemNode().modelNode().auxiliaryData("width").toInt();
style.width = qmlItemNode().modelNode().auxiliaryData("width").toInt();
qreal adjustedWidth = width / scaleFactor;
style.adjustedWidth = style.width / scaleFactor;
if (qmlItemNode().modelNode().isSelected())
width += 2;
style.width += 2;
if (m_hitTest)
width *= 8;
style.width *= 8;
QColor color = "#e71919";
style.color = "#e71919";
if (resolved.isStartLine)
color = "blue";
style.color = "blue";
if (resolved.isWildcardLine)
color = "green";
bool dash = false;
style.color = "green";
if (qmlItemNode().rootModelNode().hasAuxiliaryData("transitionColor"))
color = qmlItemNode().rootModelNode().auxiliaryData("transitionColor").value<QColor>();
style.color = qmlItemNode().rootModelNode().auxiliaryData("transitionColor").value<QColor>();
if (qmlItemNode().modelNode().hasAuxiliaryData("color"))
color = qmlItemNode().modelNode().auxiliaryData("color").value<QColor>();
style.color = qmlItemNode().modelNode().auxiliaryData("color").value<QColor>();
style.dash = false;
if (qmlItemNode().modelNode().hasAuxiliaryData("dash"))
dash = qmlItemNode().modelNode().auxiliaryData("dash").toBool();
style.dash = qmlItemNode().modelNode().auxiliaryData("dash").toBool();
int outOffset = 0;
int inOffset = 0;
style.outOffset = 0;
style.inOffset = 0;
if (qmlItemNode().modelNode().hasAuxiliaryData("outOffset"))
outOffset = qmlItemNode().modelNode().auxiliaryData("outOffset").toInt();
style.outOffset = qmlItemNode().modelNode().auxiliaryData("outOffset").toInt();
if (qmlItemNode().modelNode().hasAuxiliaryData("inOffset"))
inOffset = qmlItemNode().modelNode().auxiliaryData("inOffset").toInt();
style.inOffset = qmlItemNode().modelNode().auxiliaryData("inOffset").toInt();
int breakOffset = 50;
style.breakOffset = 50;
if (qmlItemNode().modelNode().hasAuxiliaryData("breakPoint"))
breakOffset = qmlItemNode().modelNode().auxiliaryData("breakPoint").toInt();
style.breakOffset = qmlItemNode().modelNode().auxiliaryData("breakPoint").toInt();
style.radius = 8;
if (qmlItemNode().rootModelNode().hasAuxiliaryData("transitionRadius"))
style.radius = qmlItemNode().rootModelNode().auxiliaryData("transitionRadius").toInt();
if (qmlItemNode().modelNode().hasAuxiliaryData("radius"))
style.radius = qmlItemNode().modelNode().auxiliaryData("radius").toInt();
if (resolved.isStartLine)
fromRect.translate(0, inOffset);
fromRect.translate(0, style.outOffset);
paintConnection(painter, fromRect, toRect, width, adjustedWidth ,color, dash, outOffset, inOffset, breakOffset);
paintConnection(painter, fromRect, toRect, style);
if (resolved.isStartLine) {
@@ -1121,7 +1153,7 @@ void FormEditorTransitionItem::paint(QPainter *painter, const QStyleOptionGraphi
QPen pen;
pen.setCosmetic(true);
pen.setColor(color);
pen.setColor(style.color);
painter->setPen(pen);
const int iconAdjust = 48;
@@ -1131,7 +1163,7 @@ void FormEditorTransitionItem::paint(QPainter *painter, const QStyleOptionGraphi
const int x = fromRect.topRight().x() - offset;
const int y = fromRect.topRight().y();
painter->drawRoundedRect(x, y , size - 10, size, size / 2, iconSize / 2);
drawIcon(painter, x + iconAdjust / 2, y + iconAdjust / 2, icon, iconSize, iconSize, color);
drawIcon(painter, x + iconAdjust / 2, y + iconAdjust / 2, icon, iconSize, iconSize, style.color);
}
painter->restore();

View File

@@ -47,6 +47,19 @@ namespace Internal {
class MoveController;
}
class ConnectionStyle
{
public:
qreal width;
qreal adjustedWidth;
QColor color;
bool dash;
int outOffset;
int inOffset;
int breakOffset;
int radius;
};
class QMLDESIGNERCORE_EXPORT FormEditorItem : public QGraphicsItem
{
friend class QmlDesigner::FormEditorScene;

View File

@@ -97,8 +97,11 @@ void ResizeManipulator::begin(const QPointF &/*beginPoint*/)
// return QSizeF(sizeAsPoint.x(), sizeAsPoint.y());
//}
void ResizeManipulator::update(const QPointF& updatePoint, Snapper::Snapping useSnapping)
void ResizeManipulator::update(const QPointF& updatePoint, Snapper::Snapping useSnapping, Qt::KeyboardModifiers keyMods)
{
const bool preserveAspectRatio = keyMods.testFlag(Qt::ShiftModifier);
const bool resizeFromCenter = keyMods.testFlag(Qt::AltModifier);
const double minimumWidth = 0.0;
const double minimumHeight = 0.0;
@@ -118,6 +121,16 @@ void ResizeManipulator::update(const QPointF& updatePoint, Snapper::Snapping use
QmlAnchors anchors(formEditorItem->qmlItemNode().anchors());
QRectF boundingRect(m_beginBoundingRect);
auto getRatioSizes = [&](){
double ratio = std::min(boundingRect.width() / m_beginBoundingRect.width(),
boundingRect.height() / m_beginBoundingRect.height());
double newW = m_beginBoundingRect.width() * ratio;
double newH = m_beginBoundingRect.height() * ratio;
return QSizeF(newW, newH);
};
if (m_resizeHandle->isBottomRightHandle()) {
boundingRect.setBottomRight(updatePointInLocalSpace);
@@ -132,6 +145,28 @@ void ResizeManipulator::update(const QPointF& updatePoint, Snapper::Snapping use
}
boundingRect.setBottomRight(updatePointInLocalSpace);
if (preserveAspectRatio) {
QSizeF newSize = getRatioSizes();
updatePointInLocalSpace.rx() = (boundingRect.topLeft().x() + newSize.width());
updatePointInLocalSpace.ry() = (boundingRect.topLeft().y() + newSize.height());
boundingRect.setBottomRight(updatePointInLocalSpace);
}
if (resizeFromCenter) {
QPointF grow = { boundingRect.width() - m_beginBoundingRect.width(),
boundingRect.height() - m_beginBoundingRect.height() };
if (!anchors.instanceHasAnchor(AnchorLineHorizontalCenter)
&& !anchors.instanceHasAnchor(AnchorLineVerticalCenter)) {
if (!anchors.instanceHasAnchor(AnchorLineTop))
boundingRect.setTop(boundingRect.top() - grow.y());
if (!anchors.instanceHasAnchor(AnchorLineLeft))
boundingRect.setLeft(boundingRect.left() - grow.x());
}
}
if (anchors.instanceHasAnchor(AnchorLineHorizontalCenter))
boundingRect.setLeft(boundingRect.left() - (updatePointInLocalSpace.x() - m_beginBoundingRect.right()));
@@ -144,6 +179,7 @@ void ResizeManipulator::update(const QPointF& updatePoint, Snapper::Snapping use
boundingRect.setHeight(minimumHeight);
formEditorItem->qmlItemNode().setSize(boundingRect.size());
formEditorItem->qmlItemNode().setPosition(m_beginToParentTransform.map(boundingRect.topLeft()));
if (anchors.instanceHasAnchor(AnchorLineBottom)) {
anchors.setMargin(AnchorLineBottom,
@@ -168,6 +204,28 @@ void ResizeManipulator::update(const QPointF& updatePoint, Snapper::Snapping use
}
boundingRect.setTopLeft(updatePointInLocalSpace);
if (preserveAspectRatio) {
QSizeF newSize = getRatioSizes();
updatePointInLocalSpace.rx() = (boundingRect.bottomRight().x() - newSize.width());
updatePointInLocalSpace.ry() = (boundingRect.bottomRight().y() - newSize.height());
boundingRect.setTopLeft(updatePointInLocalSpace);
}
if (resizeFromCenter) {
QPointF grow = { boundingRect.width() - m_beginBoundingRect.width(),
boundingRect.height() - m_beginBoundingRect.height() };
if (!anchors.instanceHasAnchor(AnchorLineHorizontalCenter)
&& !anchors.instanceHasAnchor(AnchorLineVerticalCenter)) {
if (!anchors.instanceHasAnchor(AnchorLineBottom))
boundingRect.setBottom(boundingRect.bottom() + grow.y());
if (!anchors.instanceHasAnchor(AnchorLineRight))
boundingRect.setRight(boundingRect.right() + grow.x());
}
}
if (anchors.instanceHasAnchor(AnchorLineHorizontalCenter))
boundingRect.setRight(boundingRect.right() - (updatePointInLocalSpace.x() - m_beginBoundingRect.left()));
@@ -208,6 +266,28 @@ void ResizeManipulator::update(const QPointF& updatePoint, Snapper::Snapping use
}
boundingRect.setTopRight(updatePointInLocalSpace);
if (preserveAspectRatio) {
QSizeF newSize = getRatioSizes();
updatePointInLocalSpace.rx() = (boundingRect.bottomLeft().x() + newSize.width());
updatePointInLocalSpace.ry() = (boundingRect.bottomLeft().y() - newSize.height());
boundingRect.setTopRight(updatePointInLocalSpace);
}
if (resizeFromCenter) {
QPointF grow = { boundingRect.width() - m_beginBoundingRect.width(),
boundingRect.height() - m_beginBoundingRect.height() };
if (!anchors.instanceHasAnchor(AnchorLineHorizontalCenter)
&& !anchors.instanceHasAnchor(AnchorLineVerticalCenter)) {
if (!anchors.instanceHasAnchor(AnchorLineBottom))
boundingRect.setBottom(boundingRect.bottom() + grow.y());
if (!anchors.instanceHasAnchor(AnchorLineLeft))
boundingRect.setLeft(boundingRect.left() - grow.x());
}
}
if (anchors.instanceHasAnchor(AnchorLineHorizontalCenter))
boundingRect.setLeft(boundingRect.left() - (updatePointInLocalSpace.x() - m_beginBoundingRect.right()));
@@ -246,6 +326,28 @@ void ResizeManipulator::update(const QPointF& updatePoint, Snapper::Snapping use
boundingRect.setBottomLeft(updatePointInLocalSpace);
if (preserveAspectRatio) {
QSizeF newSize = getRatioSizes();
updatePointInLocalSpace.rx() = (boundingRect.topRight().x() - newSize.width());
updatePointInLocalSpace.ry() = (boundingRect.topRight().y() + newSize.height());
boundingRect.setBottomLeft(updatePointInLocalSpace);
}
if (resizeFromCenter) {
QPointF grow = { boundingRect.width() - m_beginBoundingRect.width(),
boundingRect.height() - m_beginBoundingRect.height() };
if (!anchors.instanceHasAnchor(AnchorLineHorizontalCenter)
&& !anchors.instanceHasAnchor(AnchorLineVerticalCenter)) {
if (!anchors.instanceHasAnchor(AnchorLineTop))
boundingRect.setTop(boundingRect.top() - grow.y());
if (!anchors.instanceHasAnchor(AnchorLineRight))
boundingRect.setRight(boundingRect.right() + grow.x());
}
}
if (anchors.instanceHasAnchor(AnchorLineHorizontalCenter))
boundingRect.setRight(boundingRect.right() - (updatePointInLocalSpace.x() - m_beginBoundingRect.left()));
@@ -280,13 +382,30 @@ void ResizeManipulator::update(const QPointF& updatePoint, Snapper::Snapping use
boundingRect.setBottom(updatePointInLocalSpace.y());
if (resizeFromCenter) {
double grow = boundingRect.height() - m_beginBoundingRect.height();
if (!anchors.instanceHasAnchor(AnchorLineHorizontalCenter)
&& !anchors.instanceHasAnchor(AnchorLineVerticalCenter)) {
if (!anchors.instanceHasAnchor(AnchorLineTop))
boundingRect.setTop(boundingRect.top() - grow);
if (!anchors.instanceHasAnchor(AnchorLineLeft))
boundingRect.setLeft(boundingRect.left() - grow);
if (!anchors.instanceHasAnchor(AnchorLineRight))
boundingRect.setRight(boundingRect.right() + grow);
}
}
if (anchors.instanceHasAnchor(AnchorLineVerticalCenter))
boundingRect.setTop(boundingRect.top() - (updatePointInLocalSpace.y() - m_beginBoundingRect.bottom()));
if (boundingRect.width() < minimumWidth)
boundingRect.setWidth(minimumWidth);
if (boundingRect.height() < minimumHeight)
boundingRect.setHeight(minimumHeight);
formEditorItem->qmlItemNode().setSize(boundingRect.size());
formEditorItem->qmlItemNode().setPosition(m_beginToParentTransform.map(boundingRect.topLeft()));
if (anchors.instanceHasAnchor(AnchorLineBottom)) {
anchors.setMargin(AnchorLineBottom,
@@ -303,9 +422,25 @@ void ResizeManipulator::update(const QPointF& updatePoint, Snapper::Snapping use
boundingRect.setTop(updatePointInLocalSpace.y());
if (resizeFromCenter) {
double grow = boundingRect.height() - m_beginBoundingRect.height();
if (!anchors.instanceHasAnchor(AnchorLineHorizontalCenter)
&& !anchors.instanceHasAnchor(AnchorLineVerticalCenter)) {
if (!anchors.instanceHasAnchor(AnchorLineBottom))
boundingRect.setBottom(boundingRect.bottom() + grow);
if (!anchors.instanceHasAnchor(AnchorLineLeft))
boundingRect.setLeft(boundingRect.left() - grow);
if (!anchors.instanceHasAnchor(AnchorLineRight))
boundingRect.setRight(boundingRect.right() + grow);
}
}
if (anchors.instanceHasAnchor(AnchorLineVerticalCenter))
boundingRect.setBottom(boundingRect.bottom() - (updatePointInLocalSpace.y() - m_beginBoundingRect.top()));
if (boundingRect.width() < minimumWidth)
boundingRect.setWidth(minimumWidth);
if (boundingRect.height() < minimumHeight)
boundingRect.setTop(boundingRect.top() - minimumHeight + boundingRect.height());
@@ -327,13 +462,30 @@ void ResizeManipulator::update(const QPointF& updatePoint, Snapper::Snapping use
boundingRect.setRight(updatePointInLocalSpace.x());
if (resizeFromCenter) {
double grow = boundingRect.width() - m_beginBoundingRect.width();
if (!anchors.instanceHasAnchor(AnchorLineHorizontalCenter)
&& !anchors.instanceHasAnchor(AnchorLineVerticalCenter)) {
if (!anchors.instanceHasAnchor(AnchorLineTop))
boundingRect.setTop(boundingRect.top() - grow);
if (!anchors.instanceHasAnchor(AnchorLineLeft))
boundingRect.setLeft(boundingRect.left() - grow);
if (!anchors.instanceHasAnchor(AnchorLineBottom))
boundingRect.setBottom(boundingRect.bottom() + grow);
}
}
if (anchors.instanceHasAnchor(AnchorLineHorizontalCenter))
boundingRect.setLeft(boundingRect.left() - (updatePointInLocalSpace.x() - m_beginBoundingRect.right()));
if (boundingRect.width() < minimumWidth)
boundingRect.setWidth(minimumWidth);
if (boundingRect.height() < minimumHeight)
boundingRect.setHeight(minimumHeight);
formEditorItem->qmlItemNode().setSize(boundingRect.size());
formEditorItem->qmlItemNode().setPosition(m_beginToParentTransform.map(boundingRect.topLeft()));
if (anchors.instanceHasAnchor(AnchorLineRight)) {
@@ -351,11 +503,27 @@ void ResizeManipulator::update(const QPointF& updatePoint, Snapper::Snapping use
boundingRect.setLeft(updatePointInLocalSpace.x());
if (resizeFromCenter) {
double grow = boundingRect.width() - m_beginBoundingRect.width();
if (!anchors.instanceHasAnchor(AnchorLineHorizontalCenter)
&& !anchors.instanceHasAnchor(AnchorLineVerticalCenter)) {
if (!anchors.instanceHasAnchor(AnchorLineTop))
boundingRect.setTop(boundingRect.top() - grow);
if (!anchors.instanceHasAnchor(AnchorLineBottom))
boundingRect.setBottom(boundingRect.bottom() + grow);
if (!anchors.instanceHasAnchor(AnchorLineRight))
boundingRect.setRight(boundingRect.right() + grow);
}
}
if (anchors.instanceHasAnchor(AnchorLineHorizontalCenter))
boundingRect.setRight(boundingRect.right() - (updatePointInLocalSpace.x() - m_beginBoundingRect.left()));
if (boundingRect.width() < minimumWidth)
boundingRect.setLeft(boundingRect.left() - minimumWidth + boundingRect.width());
if (boundingRect.height() < minimumHeight)
boundingRect.setHeight(minimumHeight);
formEditorItem->qmlItemNode().setSize(boundingRect.size());
formEditorItem->qmlItemNode().setPosition(m_beginToParentTransform.map(boundingRect.topLeft()));

View File

@@ -46,7 +46,8 @@ public:
void removeHandle();
void begin(const QPointF& beginPoint);
void update(const QPointF& updatePoint, Snapper::Snapping useSnapping);
void update(const QPointF& updatePoint, Snapper::Snapping useSnapping,
Qt::KeyboardModifiers keyMods = Qt::NoModifier);
void end(Snapper::Snapping useSnapping);
void moveBy(double deltaX, double deltaY);

View File

@@ -71,7 +71,8 @@ void ResizeTool::mouseMoveEvent(const QList<QGraphicsItem*> &,
QGraphicsSceneMouseEvent *event)
{
if (m_resizeManipulator.isActive())
m_resizeManipulator.update(event->scenePos(), generateUseSnapping(event->modifiers()));
m_resizeManipulator.update(event->scenePos(), generateUseSnapping(event->modifiers()),
event->modifiers());
}
void ResizeTool::hoverMoveEvent(const QList<QGraphicsItem*> &itemList,

View File

@@ -289,7 +289,7 @@ void ItemLibraryModel::sortSections()
int nullPointerSectionCount = m_sections.removeAll(QPointer<ItemLibrarySection>());
QTC_ASSERT(nullPointerSectionCount == 0,;);
auto sectionSort = [](ItemLibrarySection *first, ItemLibrarySection *second) {
return QString::localeAwareCompare(first->sortingName(), second->sortingName()) < 1;
return QString::localeAwareCompare(first->sortingName(), second->sortingName()) < 0;
};
std::sort(m_sections.begin(), m_sections.end(), sectionSort);

View File

@@ -91,7 +91,7 @@ void ItemLibrarySectionModel::sortItems()
int nullPointerSectionCount = m_itemList.removeAll(QPointer<ItemLibraryItem>());
QTC_ASSERT(nullPointerSectionCount == 0,;);
auto itemSort = [](ItemLibraryItem *first, ItemLibraryItem *second) {
return QString::localeAwareCompare(first->itemName(), second->itemName()) < 1;
return QString::localeAwareCompare(first->itemName(), second->itemName()) < 0;
};
std::sort(m_itemList.begin(), m_itemList.end(), itemSort);

View File

@@ -384,7 +384,19 @@ void ItemLibraryWidget::updateModel()
{
QTC_ASSERT(m_itemLibraryModel, return);
if (m_compressionTimer.isActive()) {
m_updateRetry = false;
m_compressionTimer.stop();
}
m_itemLibraryModel->update(m_itemLibraryInfo.data(), m_model.data());
if (m_itemLibraryModel->rowCount() == 0 && !m_updateRetry) {
m_updateRetry = true; // Only retry once to avoid endless loops
m_compressionTimer.start();
} else {
m_updateRetry = false;
}
updateImports();
updateSearch();
}

View File

@@ -121,6 +121,7 @@ private:
QPointer<Model> m_model;
FilterChangeFlag m_filterFlag;
ItemLibraryEntry m_currentitemLibraryEntry;
bool m_updateRetry = false;
};
}

View File

@@ -427,12 +427,24 @@ void NavigatorView::updateItemSelection()
QItemSelection itemSelection;
foreach (const ModelNode &node, selectedModelNodes()) {
const QModelIndex index = indexForModelNode(node);
if (index.isValid()) {
const QModelIndex beginIndex(currentModel()->index(index.row(), 0, index.parent()));
const QModelIndex endIndex(currentModel()->index(index.row(), currentModel()->columnCount(index.parent()) - 1, index.parent()));
if (beginIndex.isValid() && endIndex.isValid())
itemSelection.select(beginIndex, endIndex);
}
} else {
// if the node index is invalid expand ancestors manually if they are valid.
ModelNode parentNode = node;
while (parentNode.hasParentProperty()) {
parentNode = parentNode.parentProperty().parentQmlObjectNode();
QModelIndex parentIndex = indexForModelNode(parentNode);
if (parentIndex.isValid())
treeWidget()->expand(parentIndex);
else
break;
}
}
}
bool blocked = blockSelectionChangedSignal(true);
@@ -442,7 +454,7 @@ void NavigatorView::updateItemSelection()
if (!selectedModelNodes().isEmpty())
treeWidget()->scrollTo(indexForModelNode(selectedModelNodes().constFirst()));
// make sure selected nodes a visible
// make sure selected nodes are visible
foreach (const QModelIndex &selectedIndex, itemSelection.indexes()) {
if (selectedIndex.column() == 0)
expandAncestors(selectedIndex);

View File

@@ -47,6 +47,7 @@
#include <QApplication>
#include <QDir>
#include <QFileInfo>
#include <QVector3D>
#include <QLoggingCategory>
@@ -166,6 +167,10 @@ QVariant properDefaultAuxiliaryProperties(const QmlObjectNode &qmlObjectNode,
return 0;
else if (propertyName == "breakPoint")
return 50;
else if (propertyName == "transitionRadius")
return 8;
else if (propertyName == "radius")
return 8;
else if (propertyName == "customId")
return QString();
else if (propertyName == "joinConnection")
@@ -235,7 +240,7 @@ void PropertyEditorQmlBackend::setupAuxiliaryProperties(const QmlObjectNode &qml
propertyNames.append("customId");
if (itemNode.isFlowTransition()) {
propertyNames.append({"color", "width", "inOffset", "outOffset", "dash", "breakPoint"});
propertyNames.append({"color", "width", "inOffset", "outOffset", "dash", "breakPoint", "radius"});
} else if (itemNode.isFlowItem()) {
propertyNames.append({"color", "width", "inOffset", "outOffset", "joinConnection"});
} else if (itemNode.isFlowActionArea()) {
@@ -245,7 +250,7 @@ void PropertyEditorQmlBackend::setupAuxiliaryProperties(const QmlObjectNode &qml
} else if (itemNode.isFlowWildcard()) {
propertyNames.append({"color", "width", "fillColor", "dash"});
} else if (itemNode.isFlowView()) {
propertyNames.append({"transitionColor", "areaColor", "areaFillColor", "blockColor" });
propertyNames.append({"transitionColor", "areaColor", "areaFillColor", "blockColor", "transitionRadius"});
}
for (const PropertyName &propertyName : propertyNames) {
@@ -294,11 +299,25 @@ void PropertyEditorQmlBackend::createPropertyEditorValue(const QmlObjectNode &qm
void PropertyEditorQmlBackend::setValue(const QmlObjectNode & , const PropertyName &name, const QVariant &value)
{
PropertyName propertyName = name;
propertyName.replace('.', '_');
auto propertyValue = qobject_cast<PropertyEditorValue*>(variantToQObject(m_backendValuesPropertyMap.value(QString::fromUtf8(propertyName))));
if (propertyValue)
propertyValue->setValue(value);
if (value.type() == QVariant::Vector3D) {
// Vector3D values need to be split into their subcomponents
const char *suffix[3] = {"_x", "_y", "_z"};
auto vecValue = value.value<QVector3D>();
for (int i = 0; i < 3; ++i) {
PropertyName subPropName(name.size() + 2, '\0');
subPropName.replace(0, name.size(), name);
subPropName.replace(name.size(), 2, suffix[i]);
auto propertyValue = qobject_cast<PropertyEditorValue *>(variantToQObject(m_backendValuesPropertyMap.value(QString::fromUtf8(subPropName))));
if (propertyValue)
propertyValue->setValue(QVariant(vecValue[i]));
}
} else {
PropertyName propertyName = name;
propertyName.replace('.', '_');
auto propertyValue = qobject_cast<PropertyEditorValue *>(variantToQObject(m_backendValuesPropertyMap.value(QString::fromUtf8(propertyName))));
if (propertyValue)
propertyValue->setValue(value);
}
}
QQmlContext *PropertyEditorQmlBackend::context() {

View File

@@ -29,7 +29,7 @@
#include "propertycontainer.h"
#include <QPointer>
#include <QSharedDataPointer>
#include <memory>
namespace QmlDesigner {
@@ -55,7 +55,7 @@ class QMLDESIGNERCORE_EXPORT ItemLibraryEntry
public:
ItemLibraryEntry();
~ItemLibraryEntry();
~ItemLibraryEntry() = default;
QString name() const;
TypeName typeName() const;
@@ -69,9 +69,6 @@ public:
QString qmlSource() const;
QString requiredImport() const;
ItemLibraryEntry(const ItemLibraryEntry &other);
ItemLibraryEntry& operator=(const ItemLibraryEntry &other);
using Property = QmlDesigner::PropertyContainer;
QList<Property> properties() const;
@@ -89,7 +86,7 @@ public:
void addHints(const QHash<QString, QString> &hints);
private:
QSharedDataPointer<Internal::ItemLibraryEntryData> m_data;
std::shared_ptr<Internal::ItemLibraryEntryData> m_data;
};
class QMLDESIGNERCORE_EXPORT ItemLibraryInfo : public QObject

View File

@@ -32,6 +32,7 @@
#include <QDebug>
#include <QPainter>
#include <QVector3D>
QT_BEGIN_NAMESPACE
void qt_blurImage(QPainter *painter, QImage &blurImage, qreal radius, bool quality, bool alphaOnly, int transposed = 0);
@@ -306,8 +307,38 @@ int NodeInstance::penWidth() const
QVariant NodeInstance::property(const PropertyName &name) const
{
if (isValid())
return d->propertyValues.value(name);
if (isValid()) {
if (d->propertyValues.contains(name)) {
return d->propertyValues.value(name);
} else {
// Query may be for a subproperty, e.g. scale.x
const int index = name.indexOf('.');
if (index != -1) {
PropertyName parentPropName = name.left(index);
QVariant varValue = d->propertyValues.value(parentPropName);
if (varValue.type() == QVariant::Vector3D) {
auto value = varValue.value<QVector3D>();
char subProp = name.right(1)[0];
float subValue = 0.f;
switch (subProp) {
case 'x':
subValue = value.x();
break;
case 'y':
subValue = value.y();
break;
case 'z':
subValue = value.z();
break;
default:
subValue = 0.f;
break;
}
return QVariant(subValue);
}
}
}
}
return QVariant();
}
@@ -362,6 +393,30 @@ QPair<PropertyName, qint32> NodeInstance::anchor(const PropertyName &name) const
void NodeInstance::setProperty(const PropertyName &name, const QVariant &value)
{
const int index = name.indexOf('.');
if (index != -1) {
PropertyName parentPropName = name.left(index);
QVariant oldValue = d->propertyValues.value(parentPropName);
QVector3D newValue;
if (oldValue.type() == QVariant::Vector3D)
newValue = oldValue.value<QVector3D>();
bool update = false;
if (name.endsWith(".x")) {
newValue.setX(value.toFloat());
update = true;
} else if (name.endsWith(".y")) {
newValue.setY(value.toFloat());
update = true;
} else if (name.endsWith(".z")) {
newValue.setZ(value.toFloat());
update = true;
}
if (update) {
d->propertyValues.insert(parentPropName, newValue);
return;
}
}
d->propertyValues.insert(name, value);
}

View File

@@ -510,6 +510,8 @@ QProcessEnvironment PuppetCreator::processEnvironment() const
customFileSelectors = m_target->additionalData("CustomFileSelectorsData").toStringList();
}
customFileSelectors.append("DesignMode");
if (m_availablePuppetType == FallbackPuppet)
importPaths.prepend(QLibraryInfo::location(QLibraryInfo::Qml2ImportsPath));

View File

@@ -35,12 +35,9 @@ namespace QmlDesigner {
namespace Internal {
class ItemLibraryEntryData : public QSharedData
class ItemLibraryEntryData
{
public:
ItemLibraryEntryData()
{}
QString name;
TypeName typeName;
QString category;
@@ -57,20 +54,6 @@ public:
} // namespace Internal
//
// ItemLibraryEntry
//
ItemLibraryEntry::ItemLibraryEntry(const ItemLibraryEntry &other) = default;
ItemLibraryEntry& ItemLibraryEntry::operator=(const ItemLibraryEntry &other)
{
if (this !=&other)
m_data = other.m_data;
return *this;
}
void ItemLibraryEntry::setTypeIcon(const QIcon &icon)
{
m_data->typeIcon = icon;
@@ -96,8 +79,6 @@ ItemLibraryEntry::ItemLibraryEntry() : m_data(new Internal::ItemLibraryEntryData
m_data->name.clear();
}
ItemLibraryEntry::~ItemLibraryEntry() = default;
QString ItemLibraryEntry::name() const
{
return m_data->name;

View File

@@ -258,6 +258,22 @@ void MetaInfoReader::readItemLibraryEntryProperty(const QString &name, const QVa
}
}
inline QString deEscape(const QString &value)
{
QString result = value;
result.replace(QStringLiteral("\\\""), QStringLiteral("\""));
result.replace(QStringLiteral("\\\\"), QStringLiteral("\\"));
return result;
}
inline QVariant deEscapeVariant(const QVariant &value)
{
if (value.canConvert<QString>())
return deEscape(value.toString());
return value;
}
void MetaInfoReader::readPropertyProperty(const QString &name, const QVariant &value)
{
if (name == QStringLiteral("name")) {
@@ -265,7 +281,7 @@ void MetaInfoReader::readPropertyProperty(const QString &name, const QVariant &v
} else if (name == QStringLiteral("type")) {
m_currentPropertyType = value.toString();
} else if (name == QStringLiteral("value")) {
m_currentPropertyValue = value;
m_currentPropertyValue = deEscapeVariant(value);
} else {
addError(tr("Unknown property for Property %1").arg(name), currentSourceLocation());
setParserState(Error);

View File

@@ -90,11 +90,12 @@ bool QmlTimeline::hasTimeline(const ModelNode &node, const PropertyName &propert
for (const ModelNode &childNode : modelNode().defaultNodeListProperty().toModelNodeList()) {
if (QmlTimelineKeyframeGroup::isValidQmlTimelineKeyframeGroup(childNode)) {
const QmlTimelineKeyframeGroup frames(childNode);
if (frames.target().isValid()
&& frames.target() == node
&& frames.propertyName() == propertyName)
if (frames.target().isValid() && frames.target() == node
&& (frames.propertyName() == propertyName
|| (frames.propertyName().contains('.')
&& frames.propertyName().startsWith(propertyName)))) {
return true;
}
}
}
}

View File

@@ -212,6 +212,13 @@ void DesignModeWidget::disableWidgets()
m_isDisabled = true;
}
static void addSpacerToToolBar(QToolBar *toolBar)
{
QWidget* empty = new QWidget();
empty->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Preferred);
toolBar->addWidget(empty);
}
void DesignModeWidget::setup()
{
auto &actionManager = viewManager().designerActionManager();
@@ -366,6 +373,7 @@ void DesignModeWidget::setup()
// Create toolbars
auto toolBar = new QToolBar();
toolBar->addAction(viewManager().componentViewAction());
toolBar->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
DesignerActionToolBar *designerToolBar = QmlDesignerPlugin::instance()->viewManager().designerActionManager().createToolBar(m_toolBar);
@@ -407,6 +415,8 @@ void DesignModeWidget::setup()
}
});
addSpacerToToolBar(toolBar);
auto workspaceComboBox = new QComboBox();
workspaceComboBox->setMinimumWidth(120);
workspaceComboBox->setToolTip(tr("Switch the active workspace."));