forked from qt-creator/qt-creator
QmlDesigner: Allow inserting SVG snippets
Allows to paste SVG clipboard content into the Form Editor. It will create a Group item which acts as the SVGs view box and groups multiple items together. All SVG items will be transformed into SvgPathItem. * Supports all basic SVG shapes path, rect, polygon, circle, ellipse * Supports the following SVG presentation attributes as CSS-inline definition, XML-attribute, style element: fill, stroke, stroke-width, opacity, fill-opacity, stroke-opacity * Supports all transform operations Task-number: QDS-5259 Change-Id: I9b7027992de60e5c87f2031251348dbb31fe03fe Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
committed by
Thomas Hartmann
parent
dbd5a4fe1b
commit
14c4f257fe
@@ -7,7 +7,7 @@ add_qtc_plugin(QmlDesigner
|
||||
CONDITION TARGET Qt5::QuickWidgets
|
||||
DEPENDS
|
||||
QmlJS LanguageUtils QmlEditorWidgets AdvancedDockingSystem
|
||||
Qt5::QuickWidgets Qt5::CorePrivate Sqlite
|
||||
Qt5::QuickWidgets Qt5::CorePrivate Sqlite Qt5::Xml Qt5::Svg
|
||||
DEFINES
|
||||
DESIGNER_CORE_LIBRARY
|
||||
IDE_LIBRARY_BASENAME=\"${IDE_LIBRARY_BASE_PATH}\"
|
||||
@@ -139,6 +139,7 @@ extend_qtc_plugin(QmlDesigner
|
||||
theme.cpp theme.h
|
||||
zoomaction.cpp zoomaction.h
|
||||
hdrimage.cpp hdrimage.h
|
||||
svgpasteaction.cpp svgpasteaction.h
|
||||
)
|
||||
|
||||
extend_qtc_plugin(QmlDesigner
|
||||
|
@@ -20,6 +20,7 @@ SOURCES += crumblebar.cpp
|
||||
SOURCES += qmldesignericonprovider.cpp
|
||||
SOURCES += zoomaction.cpp
|
||||
SOURCES += hdrimage.cpp
|
||||
SOURCES += svgpasteaction.cpp
|
||||
|
||||
HEADERS += modelnodecontextmenu.h
|
||||
HEADERS += addimagesdialog.h
|
||||
@@ -43,6 +44,7 @@ HEADERS += crumblebar.h
|
||||
HEADERS += qmldesignericonprovider.h
|
||||
HEADERS += zoomaction.h
|
||||
HEADERS += hdrimage.h
|
||||
HEADERS += svgpasteaction.h
|
||||
|
||||
FORMS += \
|
||||
$$PWD/addsignalhandlerdialog.ui
|
||||
|
1232
src/plugins/qmldesigner/components/componentcore/svgpasteaction.cpp
Normal file
1232
src/plugins/qmldesigner/components/componentcore/svgpasteaction.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,56 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2021 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.
|
||||
**
|
||||
****************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <qmlitemnode.h>
|
||||
|
||||
#include <QDomDocument>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
struct CSSProperty
|
||||
{
|
||||
QString directive;
|
||||
QString value;
|
||||
};
|
||||
|
||||
using CSSRule = std::vector<CSSProperty>;
|
||||
using CSSRules = QHash<QString, CSSRule>;
|
||||
using PropertyMap = QHash<QByteArray, QVariant>;
|
||||
|
||||
class SVGPasteAction
|
||||
{
|
||||
public:
|
||||
SVGPasteAction();
|
||||
|
||||
bool containsSVG(const QString &str);
|
||||
|
||||
QmlObjectNode createQmlObjectNode(QmlDesigner::ModelNode &targetNode);
|
||||
|
||||
private:
|
||||
QDomDocument m_domDocument;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
@@ -51,9 +51,12 @@
|
||||
#include <coreplugin/editormanager/editormanager.h>
|
||||
#include <utils/algorithm.h>
|
||||
#include <timelineactions.h>
|
||||
#include <svgpasteaction.h>
|
||||
|
||||
#include <qmljs/qmljsmodelmanagerinterface.h>
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QFileInfo>
|
||||
#include <QUrl>
|
||||
#include <QDebug>
|
||||
@@ -62,6 +65,7 @@
|
||||
#include <QMessageBox>
|
||||
#include <QPlainTextEdit>
|
||||
#include <QRandomGenerator>
|
||||
#include <QClipboard>
|
||||
|
||||
using namespace ProjectExplorer;
|
||||
|
||||
@@ -171,6 +175,41 @@ Model* DesignDocument::createInFileComponentModel()
|
||||
return model;
|
||||
}
|
||||
|
||||
bool DesignDocument::pasteSVG()
|
||||
{
|
||||
SVGPasteAction svgPasteAction;
|
||||
|
||||
if (!svgPasteAction.containsSVG(QApplication::clipboard()->text()))
|
||||
return false;
|
||||
|
||||
rewriterView()->executeInTransaction("DesignDocument::paste1", [&]() {
|
||||
ModelNode targetNode;
|
||||
|
||||
// If nodes are currently selected make the first node in selection the target
|
||||
if (!view()->selectedModelNodes().isEmpty())
|
||||
targetNode = view()->firstSelectedModelNode();
|
||||
|
||||
// If target is still invalid make the root node the target
|
||||
if (!targetNode.isValid())
|
||||
targetNode = view()->rootModelNode();
|
||||
|
||||
// Check if document has studio components import, if not create it
|
||||
QmlDesigner::Import import = QmlDesigner::Import::createLibraryImport("QtQuick.Studio.Components", "1.0");
|
||||
if (!currentModel()->hasImport(import, true, true)) {
|
||||
QmlDesigner::Import studioComponentsImport = QmlDesigner::Import::createLibraryImport("QtQuick.Studio.Components", "1.0");
|
||||
try {
|
||||
currentModel()->changeImports({studioComponentsImport}, {});
|
||||
} catch (const QmlDesigner::Exception &) {
|
||||
QTC_ASSERT(false, return);
|
||||
}
|
||||
}
|
||||
|
||||
svgPasteAction.createQmlObjectNode(targetNode);
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QList<DocumentMessage> DesignDocument::qmlParseWarnings() const
|
||||
{
|
||||
return m_rewriterView->warnings();
|
||||
@@ -495,6 +534,9 @@ static void scatterItem(const ModelNode &pastedNode, const ModelNode &targetNode
|
||||
|
||||
void DesignDocument::paste()
|
||||
{
|
||||
if (pasteSVG())
|
||||
return;
|
||||
|
||||
if (TimelineActions::clipboardContainsKeyframes()) // pasting keyframes is handled in TimelineView
|
||||
return;
|
||||
|
||||
@@ -518,7 +560,7 @@ void DesignDocument::paste()
|
||||
ModelNode targetNode;
|
||||
|
||||
if (!view.selectedModelNodes().isEmpty())
|
||||
targetNode = view.selectedModelNodes().constFirst();
|
||||
targetNode = view.firstSelectedModelNode();
|
||||
|
||||
// in case we copy and paste a selection we paste in the parent item
|
||||
if ((view.selectedModelNodes().count() == selectedNodes.count()) && targetNode.isValid() && targetNode.hasParentProperty()) {
|
||||
@@ -572,7 +614,7 @@ void DesignDocument::paste()
|
||||
ModelNode targetNode;
|
||||
|
||||
if (!view.selectedModelNodes().isEmpty()) {
|
||||
targetNode = view.selectedModelNodes().constFirst();
|
||||
targetNode = view.firstSelectedModelNode();
|
||||
} else {
|
||||
// if selection is empty and this is a 3D Node, paste it under the active scene
|
||||
if (pastedNode.isSubclassOf("QtQuick3D.Node")) {
|
||||
|
@@ -145,6 +145,8 @@ private: // functions
|
||||
|
||||
Model *createInFileComponentModel();
|
||||
|
||||
bool pasteSVG();
|
||||
|
||||
private: // variables
|
||||
QScopedPointer<Model> m_documentModel;
|
||||
QScopedPointer<Model> m_inFileComponentModel;
|
||||
|
@@ -1,4 +1,4 @@
|
||||
QT += quickwidgets core-private
|
||||
QT += quickwidgets core-private xml svg
|
||||
CONFIG += exceptions
|
||||
|
||||
INCLUDEPATH += $$PWD
|
||||
|
@@ -10,7 +10,7 @@ Project {
|
||||
Depends {
|
||||
name: "Qt";
|
||||
submodules: [
|
||||
"core-private", "quickwidgets"
|
||||
"core-private", "quickwidgets", "xml", "svg"
|
||||
]
|
||||
}
|
||||
Depends { name: "AdvancedDockingSystem" }
|
||||
@@ -482,6 +482,8 @@ Project {
|
||||
"componentcore/zoomaction.h",
|
||||
"componentcore/hdrimage.cpp",
|
||||
"componentcore/hdrimage.h",
|
||||
"componentcore/svgpasteaction.cpp",
|
||||
"componentcore/svgpasteaction.h",
|
||||
"texteditor/texteditorstatusbar.cpp",
|
||||
"texteditor/texteditorstatusbar.h",
|
||||
"componentcore/changestyleaction.cpp",
|
||||
|
Reference in New Issue
Block a user