Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_shape_controller.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2007 Boudewijn Rempt <boud@valdyas.org>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
8
9
10#include <klocalizedstring.h>
11
12#include <KoShape.h>
13#include <KoShapeContainer.h>
14#include <KoShapeManager.h>
15#include <KoCanvasBase.h>
16#include <KoToolManager.h>
17#include <KisView.h>
18#include <KoSelection.h>
19#include <KoShapeLayer.h>
20#include <KoPathShape.h>
22#include <KoCanvasController.h>
23
24#include "kis_node_manager.h"
25#include "kis_shape_selection.h"
26#include "kis_selection.h"
29#include "kis_clone_layer.h"
30#include "canvas/kis_canvas2.h"
31#include "KisDocument.h"
32#include "kis_image.h"
33#include "kis_group_layer.h"
34#include "kis_node_shape.h"
36#include "kis_name_server.h"
37#include "kis_mask.h"
38#include "kis_shape_layer.h"
39#include "KisViewManager.h"
40#include "kis_node.h"
41
44#include <kis_undo_adapter.h>
47
49
50
59
60KisShapeController::KisShapeController(KisNameServer *nameServer, KUndo2Stack *undoStack, QObject *parent)
61 : KisDummiesFacadeBase(parent)
62 , m_d(new Private())
63{
64 m_d->nameServer = nameServer;
65 resourceManager()->setUndoStack(undoStack);
66}
67
68
70{
72 if (node) {
74 }
75
76 delete m_d;
77}
78
88
97
99{
100 KisNodeShape *newShape =
101 m_d->shapesGraph.addNode(node, parent, aboveThis);
102 // XXX: what are we going to do with this shape?
103 Q_UNUSED(newShape);
104
105 KisShapeLayer *shapeLayer = dynamic_cast<KisShapeLayer*>(node.data());
106 if (shapeLayer) {
111 connect(shapeLayer, SIGNAL(selectionChanged()),
112 SIGNAL(selectionChanged()));
113 connect(shapeLayer->shapeManager(), SIGNAL(selectionContentChanged()),
114 SIGNAL(selectionContentChanged()));
115 connect(shapeLayer, SIGNAL(currentLayerChanged(const KoShapeLayer*)),
116 SIGNAL(currentLayerChanged(const KoShapeLayer*)));
117 }
118}
119
121{
122 KisShapeLayer *shapeLayer = dynamic_cast<KisShapeLayer*>(node.data());
123 if (shapeLayer) {
124 shapeLayer->disconnect(this);
125 }
126
128}
129
131{
132 return m_d->shapesGraph.containsNode(node);
133}
134
139
144
146{
147 return m_d->shapesGraph.shapesCount();
148}
149static inline bool belongsToShapeSelection(KoShape* shape) {
150 return dynamic_cast<KisShapeSelectionMarker*>(shape->userData());
151}
152
154{
155 KoShapeContainer *resultParent = 0;
156 KisCommandUtils::CompositeCommand *resultCommand =
157 new KisCommandUtils::CompositeCommand(parentCommand);
158
159 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(!shapes.isEmpty(), resultParent);
160 Q_FOREACH (KoShape *shape, shapes) {
162 }
163
165 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(canvas, resultParent);
166
167 const bool baseBelongsToSelection = belongsToShapeSelection(shapes.first());
168 bool allSameBelongsToShapeSelection = true;
169
170 Q_FOREACH (KoShape *shape, shapes) {
171 allSameBelongsToShapeSelection &= belongsToShapeSelection(shape) == baseBelongsToSelection;
172 }
173
174 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(!baseBelongsToSelection || allSameBelongsToShapeSelection, resultParent);
175
176 if (baseBelongsToSelection && allSameBelongsToShapeSelection) {
177 KisSelectionSP selection = canvas->viewManager()->selection();
178 if (selection) {
179 KisSelectionComponent* shapeSelectionComponent = selection->shapeSelection();
180
181 if (!shapeSelectionComponent) {
182 shapeSelectionComponent = new KisShapeSelection(this, selection);
183 resultCommand->addCommand(selection->convertToVectorSelection(shapeSelectionComponent));
184 }
185
186 KisShapeSelection * shapeSelection = static_cast<KisShapeSelection*>(shapeSelectionComponent);
187 resultParent = shapeSelection;
188 }
189 } else {
190 KisShapeLayer *shapeLayer =
191 dynamic_cast<KisShapeLayer*>(
193
194 if (!shapeLayer || forceNewLayer) {
195 shapeLayer = new KisShapeLayer(this, image(),
196 i18n("Vector Layer %1", m_d->nameServer->number()),
198
199 resultCommand->addCommand(
201 shapeLayer,
202 image()->rootLayer(),
203 image()->rootLayer()->childCount()));
204 }
205
206 resultParent = shapeLayer;
207 }
208
209 return resultParent;
210}
211
213{
214 KisImageSP image = this->image();
215 return image ? image->bounds() : QRect(0, 0, 666, 777);
216}
217
219{
220 KisImageSP image = this->image();
221 return image ? image->xRes() * 72.0 : 72.0;
222}
223
225{
226 if (!image()) return;
227
228 KisNodeSP rootNode = image()->root();
229
230 if (m_d->shapesGraph.containsNode(rootNode)) {
231 Q_ASSERT(canvas);
232 Q_ASSERT(canvas->shapeManager());
233 KoSelection *selection = canvas->shapeManager()->selection();
234 if (selection && m_d->shapesGraph.nodeToShape(rootNode)) {
235 selection->select(m_d->shapesGraph.nodeToShape(rootNode));
236 KoToolManager::instance()->switchToolRequested(KoToolManager::instance()->preferredToolForSelection(selection->selectedShapes()));
237 }
238 }
239}
240
242{
244
245 if (image) {
246 m_d->imageConnections.addConnection(image, SIGNAL(sigResolutionChanged(double, double)), this, SLOT(slotUpdateDocumentResolution()));
247 m_d->imageConnections.addConnection(image, SIGNAL(sigSizeChanged(QPointF, QPointF)), this, SLOT(slotUpdateDocumentSize()));
248 }
249
251
254}
255
257{
258 if (node) {
259 return m_d->shapesGraph.nodeToShape(node);
260 }
261 return 0;
262}
263
const quint8 OPACITY_OPAQUE_U8
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
KisSelectedShapesProxy selectedShapesProxy
KoShapeManager shapeManager
KisViewManager * viewManager() const
void setImage(KisImageWSP image)
The command for adding a layer.
double xRes() const
QRect bounds() const override
KisNodeSP node() const
bool containsNode(KisNodeSP node) const
KisNodeDummy * nodeToDummy(KisNodeSP node)
KisNodeDummy * rootDummy() const
KisNodeShape * addNode(KisNodeSP node, KisNodeSP parent, KisNodeSP aboveThis)
KisNodeShape * nodeToShape(KisNodeSP node)
void removeNode(KisNodeSP node)
KoSelection * selection() override
void setImage(KisImageWSP image, KisNodeSP activeNode) override
qreal pixelsPerInch() const override
bool hasDummyForNode(KisNodeSP node) const override
int dummiesCount() const override
void addNodeImpl(KisNodeSP node, KisNodeSP parent, KisNodeSP aboveThis) override
KisNodeDummy * rootDummy() const override
KisShapeController(KisNameServer *nameServer, KUndo2Stack *undoStack, QObject *parent=0)
void setInitialShapeForCanvas(KisCanvas2 *canvas)
void currentLayerChanged(const KoShapeLayer *)
void selectionContentChanged()
QRectF documentRectInPixels() const override
void removeNodeImpl(KisNodeSP node) override
KoShapeLayer * shapeForNode(KisNodeSP layer) const
KisNodeDummy * dummyForNode(KisNodeSP layer) const override
KoShapeContainer * createParentForShapes(const QList< KoShape * > shapes, bool forceNewLayer, KUndo2Command *parentCommand) override
KoShapeManager * shapeManager() const
void addConnection(Sender sender, Signal signal, Receiver receiver, Method method, Qt::ConnectionType type=Qt::AutoConnection)
KisSelectionSP selection()
virtual KoCanvasBase * canvas() const
void setUndoStack(KUndo2Stack *undoStack)
void setResource(int key, const QVariant &value)
@ DocumentRectInPixels
Bounds of the document in pixels.
@ DocumentResolution
Pixels-per-inch resolution of the document.
void select(KoShape *shape)
const QList< KoShape * > selectedShapes() const
KoShapeLayer * activeLayer() const
virtual KoDocumentResourceManager * resourceManager() const
KoSelection * selection
KoShapeUserData * userData() const
Definition KoShape.cpp:710
KoShapeContainer * parent() const
Definition KoShape.cpp:1039
void switchToolRequested(const QString &id)
KoCanvasController * activeCanvasController() const
static KoToolManager * instance()
Return the toolmanager singleton.
#define KIS_SAFE_ASSERT_RECOVER_BREAK(cond)
Definition kis_assert.h:127
#define KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(cond, val)
Definition kis_assert.h:129
static bool belongsToShapeSelection(KoShape *shape)
KUndo2Command * convertToVectorSelection(KisSelectionComponent *shapeSelection)
converts shape selection into the vector state
KisSelectionComponent * shapeSelection
KisSignalAutoConnectionsStore imageConnections