Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_selection_action_factories.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2012 Dmitry Kazakov <dimula73@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
8
9#include <QMimeData>
10
11#include <klocalizedstring.h>
12#include <kundo2command.h>
13
14#include <KisMainWindow.h>
15#include <KisDocument.h>
16#include <KisPart.h>
17#include <KoPathShape.h>
18#include <KoShapeController.h>
19#include <KoShapeRegistry.h>
21#include <KoShapeManager.h>
22#include <KoSelection.h>
24#include <KoShapeStroke.h>
25#include <KoDocumentInfo.h>
26#include <KoCanvasBase.h>
27
28#include "KisViewManager.h"
30#include "kis_clipboard.h"
31#include "kis_pixel_selection.h"
32#include "kis_paint_layer.h"
33#include "kis_image.h"
34#include "KisImageBarrierLock.h"
35#include "kis_fill_painter.h"
36#include "kis_transaction.h"
37#include "kis_iterator_ng.h"
39#include "kis_group_layer.h"
42#include "kis_tool_proxy.h"
43#include "kis_canvas2.h"
48#include "kis_shape_selection.h"
49#include "kis_shape_layer.h"
52#include "kis_time_span.h"
54#include "kis_node_manager.h"
55#include "kis_layer_utils.h"
56#include <kis_selection_mask.h>
58
64
67
68#include <kis_tool_utils.h>
69
70
72{
73 KisImageWSP image = view->image();
74 if (!image) return;
75
76 if (view->canvasBase()->toolProxy()->selectAll()) {
77 return;
78 }
79
80 KisProcessingApplicator *ap = beginAction(view, kundo2_i18n("Select All"));
81
83 [image] () {
84 return !image->globalSelection() ?
86 }),
89
90 struct SelectAll : public KisTransactionBasedCommand {
91 SelectAll(KisImageSP image) : m_image(image) {}
92 KisImageSP m_image;
93 KUndo2Command* paint() override {
94 KisSelectionSP selection = m_image->globalSelection();
95 KisSelectionTransaction transaction(selection->pixelSelection());
96 selection->pixelSelection()->clear();
97 selection->pixelSelection()->select(m_image->bounds());
98 return transaction.endAndTake();
99 }
100 };
101
102 ap->applyCommand(new SelectAll(image),
105
106 endAction(ap, KisOperationConfiguration(id()).toXML());
107}
108
110{
111 KisImageWSP image = view->image();
112 if (!image) return;
113
114 if (view->canvasBase()->toolProxy()->hasSelection()) {
115 // see KisCutCopyActionFactory::run
116 KisImageBarrierLock lock(image, std::try_to_lock);
117 if (!lock.owns_lock()) return;
118
119 view->canvasBase()->toolProxy()->deselect();
120 return;
121 }
122
124
125 KisProcessingApplicator *ap = beginAction(view, cmd->text());
127 endAction(ap, KisOperationConfiguration(id()).toXML());
128}
129
131{
132 KisImageWSP image = view->image();
133 if (!image) return;
134
136
137 KisProcessingApplicator *ap = beginAction(view, cmd->text());
139 endAction(ap, KisOperationConfiguration(id()).toXML());
140}
141
142void KisFillActionFactory::run(const QString &fillSource, KisViewManager *view)
143{
144 KisNodeSP node = view->activeNode();
145 if (!node || !node->hasEditablePaintDevice()) return;
146
147 KisImageWSP image = view->image();
148
149 KisSelectionSP selection = view->selection();
150
151 bool usePattern = false;
152 bool useBgColor = false;
153 if (fillSource.contains("pattern")) {
154 usePattern = true;
155 } else if (fillSource.contains("bg")) {
156 useBgColor = true;
157 }
158
159 KisResourcesSnapshotSP resources =
161 if (!fillSource.contains("opacity")) {
162 resources->setOpacity(1.0);
163 }
164
167 kundo2_i18n("Flood Fill Layer"), false, image.data()
168 );
169 strategy->setSupportsWrapAroundMode(true);
170 KisStrokeId fillStrokeId = image->startStroke(strategy);
171 KIS_SAFE_ASSERT_RECOVER_RETURN(fillStrokeId);
172
173 QSharedPointer<QRect> dirtyRect = QSharedPointer<QRect>(new QRect);
174
175 FillProcessingVisitor *visitor = new FillProcessingVisitor(nullptr, selection, resources);
176 visitor->setSeedPoint(QPoint(0, 0));
177 visitor->setSelectionOnly(true);
178 visitor->setOutDirtyRect(dirtyRect);
179 visitor->setUsePattern(usePattern);
180 visitor->setUseBgColor(useBgColor);
181
182 image->addJob(
183 fillStrokeId,
185 KUndo2CommandSP(new KisProcessingCommand(visitor, node)),
186 false,
189 )
190 );
191
192 image->addJob(
193 fillStrokeId,
195 KUndo2CommandSP(new KisUpdateCommand(node, dirtyRect, image.data())),
196 false,
199 )
200 );
201
202 image->endStroke(fillStrokeId);
203
205}
206
208{
209 // XXX: "Add saving of XML data for Clear action"
210
212}
213
215{
216 // XXX: "Add saving of XML data for Image Resize To Selection action"
217
218 KisSelectionSP selection = view->selection();
219 if (!selection) return;
220
221 view->image()->cropImage(selection->selectedExactRect());
222}
223
225{
226 KisImageSP image = view->image();
227 if (!image) return;
228
229 if (!view->blockUntilOperationsFinished(image)) return;
230
231 // Reference layers is a fake node, so it isn't added to the layer stack, this results in KisSelectedShapesProxy not
232 // being aware of the active shapeManager and its selected shapes.
233 const auto currentToolHasSelection =
234 view->canvasBase()->toolProxy()->hasSelection();
235
236 const bool haveShapesSelected =
238
239 KisSelectionSP selection = view->selection();
240
241 const bool skipShapes = selection && !currentToolHasSelection;
242
243 if (!skipShapes && !flags.testFlag(SharpClip) && (haveShapesSelected || currentToolHasSelection)) {
244 // XXX: "Add saving of XML data for Cut/Copy of shapes"
245
251 KisImageBarrierLock lock(image, std::try_to_lock);
252 if (!lock.owns_lock()) return;
253
254 if (flags & CutClip) {
255 view->canvasBase()->toolProxy()->cut();
256 } else {
257 view->canvasBase()->toolProxy()->copy();
258 }
259 } else if (selection) {
260 KisNodeList selectedNodes = view->nodeManager()->selectedNodes();
261
262 KisNodeList masks;
263 Q_FOREACH (KisNodeSP node, selectedNodes) {
264 if (node->inherits("KisMask")) {
265 masks.append(node);
266 }
267 }
268
269 selectedNodes = KisLayerUtils::sortAndFilterMergeableInternalNodes(selectedNodes);
270
271 KisNodeList nodes;
272 Q_FOREACH (KisNodeSP node, selectedNodes) {
273 KisNodeSP dupNode;
274 if (node->inherits("KisShapeLayer") || node->inherits("KisFileLayer")
275
276 // also recreate the node for animated layers, since we have no
277 // API for making a node non-animated
278 || (node->inherits("KisPaintLayer") && node->isAnimated())) {
279
280 KisPaintDeviceSP dev = new KisPaintDevice(*node->projection());
281 // might have to change node's name (vector to paint layer)
282 dupNode = new KisPaintLayer(image, node->name(), node->opacity(), dev);
283 } else {
284 dupNode = node->clone();
285 }
286 nodes.append(dupNode);
287 }
288
289 Q_FOREACH (KisNodeSP node, nodes) {
290 KisLayerUtils::recursiveApplyNodes(node, [image, view, flags] (KisNodeSP node) {
291 if (node && node->paintDevice() && !node->inherits("KisMask")) {
292 KisToolUtils::trimDeviceForClipboard(image, node->paintDevice(), view->selection(), flags.testFlag(SharpClip));
293 }
294 });
295 }
296
297 KisImageSP tempImage = KisToolUtils::buildImageForClipboard(image, nodes);
298 KisClipboard::instance()->setLayers(nodes, tempImage, selection->selectedExactRect());
299
300
301 KUndo2MagicString actionName = flags & CutClip ?
302 kundo2_i18n("Cut") :
303 kundo2_i18n("Copy");
305 beginAction(view,
306 actionName,
308
309 if (flags & CutClip) {
310 selectedNodes.append(masks);
311 Q_FOREACH (KisNodeSP node, selectedNodes) {
312 KisLayerUtils::recursiveApplyNodes(node, [selection, masks, ap] (KisNodeSP node){
313
314 if (!node->hasEditablePaintDevice()) {
315 return;
316 }
317
318 // applied on masks if selected explicitly (when CTRL-X(cut) is used for deletion)
319 if (node->inherits("KisMask") && !masks.contains(node)) {
320 return;
321 }
322
323 struct ClearSelection : public KisTransactionBasedCommand {
324 ClearSelection(KisNodeSP node, KisSelectionSP sel)
325 : m_node(node), m_sel(sel) {}
326 KisNodeSP m_node;
327 KisSelectionSP m_sel;
328
329 KUndo2Command* paint() override {
330 KisSelectionSP cutSelection = m_sel;
331 // Shrinking the cutting area was previously used
332 // for getting seamless cut-paste. Now we use makeSharpClip
333 // instead.
334 // QRect originalRect = cutSelection->selectedExactRect();
335 // static const int preciseSelectionThreshold = 16;
336 //
337 // if (originalRect.width() > preciseSelectionThreshold ||
338 // originalRect.height() > preciseSelectionThreshold) {
339 // cutSelection = new KisSelection(*m_sel);
340 // delete cutSelection->flatten();
341 //
342 // KisSelectionFilter* filter = new KisShrinkSelectionFilter(1, 1, false);
343 //
344 // QRect processingRect = filter->changeRect(originalRect);
345 // filter->process(cutSelection->pixelSelection(), processingRect);
346 // }
347
348 KisTransaction transaction(m_node->paintDevice());
349 m_node->paintDevice()->clearSelection(cutSelection);
350 m_node->setDirty(cutSelection->selectedRect());
351 return transaction.endAndTake();
352 }
353 };
354
355 KUndo2Command *command = new ClearSelection(node, selection);
357
358 });
359 }
360 }
361
362 KisOperationConfiguration config(id());
363 config.setProperty("will-cut", flags.testFlag(CutClip));
364 config.setProperty("use-sharp-clip", flags.testFlag(SharpClip));
365 endAction(ap, config.toXML());
366 } else if (!flags.testFlag(SharpClip)) {
367 if (flags & CutClip) {
369 } else {
371 }
372 }
373}
374
376{
377 KisImageWSP image = view->image();
378 if (!image) return;
379 if (!view->blockUntilOperationsFinished(image)) return;
380
381 image->barrierLock();
382 KisPaintDeviceSP dev = new KisPaintDevice(*image->root()->projection());
384
385 KisNodeSP node = new KisPaintLayer(image, "Projection", OPACITY_OPAQUE_U8, dev);
386 KisNodeList nodes{node};
387
388 KisImageSP tempImage = KisToolUtils::buildImageForClipboard(image, nodes);
389 KisClipboard::instance()->setLayers(nodes, tempImage, view->selection() ? view->selection()->selectedExactRect() : image->bounds());
390 image->unlock();
391
393 endAction(ap, KisOperationConfiguration(id()).toXML());
394}
395
397{
399
400 runFilter(filter, view, config);
401}
402
404{
405 KisSelectionSP selection = view->selection();
406
407 if (selection->hasShapeSelection()) {
408 view->showFloatingMessage(i18nc("floating message",
409 "Selection is already in a vector format "),
410 QIcon(), 2000, KisFloatingMessage::Low);
411 return;
412 }
413
414 if (!selection->outlineCacheValid()) {
415 view->image()->addSpontaneousJob(new KisUpdateOutlineJob(selection, false, Qt::transparent));
416 if (!view->blockUntilOperationsFinished(view->image())) {
417 return;
418 }
419 }
420
421 QPainterPath selectionOutline = selection->outlineCache();
422 QTransform transform = view->canvasBase()->coordinatesConverter()->imageToDocumentTransform();
423
424 KoShape *shape = KoPathShape::createShapeFromPainterPath(transform.map(selectionOutline));
426
430 if(!shape->userData()) {
432 }
433
434 KisProcessingApplicator *ap = beginAction(view, kundo2_i18n("Convert to Vector Selection"));
435
436 ap->applyCommand(view->canvasBase()->shapeController()->addShape(shape, 0),
439
440 endAction(ap, KisOperationConfiguration(id()).toXML());
441}
442
444{
445 KisSelectionSP selection = view->selection();
446
447 if (!selection->hasShapeSelection()) {
448 view->showFloatingMessage(i18nc("floating message",
449 "Selection is already in a raster format "),
450 QIcon(), 2000, KisFloatingMessage::Low);
451 return;
452 }
453
454 KisProcessingApplicator *ap = beginAction(view, kundo2_i18n("Convert to Vector Selection"));
455
456 struct RasterizeSelection : public KisTransactionBasedCommand {
457 RasterizeSelection(KisSelectionSP sel)
458 : m_sel(sel) {}
459 KisSelectionSP m_sel;
460
461 KUndo2Command* paint() override {
462 // just create an empty transaction: it will rasterize the
463 // selection and Q_EMIT the necessary signals
464
465 KisTransaction transaction(m_sel->pixelSelection());
466 return transaction.endAndTake();
467 }
468 };
469
470 ap->applyCommand(new RasterizeSelection(selection),
473
474 endAction(ap, KisOperationConfiguration(id()).toXML());
475}
476
478{
479 const QList<KoShape*> originalShapes = view->canvasBase()->shapeManager()->selection()->selectedShapes();
480
481 bool hasSelectionShapes = false;
482 QList<KoShape*> clonedShapes;
483
484 Q_FOREACH (KoShape *shape, originalShapes) {
485 if (dynamic_cast<KisShapeSelectionMarker*>(shape->userData())) {
486 hasSelectionShapes = true;
487 continue;
488 }
489
490 clonedShapes << shape->cloneShapeAndBakeAbsoluteTransform();
491 }
492
493 if (clonedShapes.isEmpty()) {
494 if (hasSelectionShapes) {
495 view->showFloatingMessage(i18nc("floating message",
496 "The shape already belongs to a selection"),
497 QIcon(), 2000, KisFloatingMessage::Low);
498 }
499 return;
500 }
501
502 KisSelectionToolHelper helper(view->canvasBase(), kundo2_i18n("Convert shapes to vector selection"));
503 helper.addSelectionShapes(clonedShapes);
504}
505
507{
508 KisSelectionSP selection = view->selection();
509 if (!selection->outlineCacheValid()) {
510 return;
511 }
512
513 QPainterPath selectionOutline = selection->outlineCache();
514 QTransform transform = view->canvasBase()->coordinatesConverter()->imageToDocumentTransform();
515
516 KoShape *shape = KoPathShape::createShapeFromPainterPath(transform.map(selectionOutline));
518
519 KoColor fgColor = view->canvasBase()->resourceManager()->resource(KoCanvasResource::ForegroundColor).value<KoColor>();
520 KoShapeStrokeSP border(new KoShapeStroke(1.0, fgColor.toQColor()));
521 shape->setStroke(border);
522
523 KUndo2Command *cmd = view->canvasBase()->shapeController()->addShapeDirect(shape, 0);
525}
526
528{
529 KisImageWSP image = view->image();
530 if (!image) {
531 return;
532 }
533
534 KisSelectionSP selection = view->selection();
535 if (!selection) {
536 return;
537 }
538
539 int size = params.lineSize;
540
541 KisPixelSelectionSP pixelSelection = selection->projection();
542 if (!pixelSelection->outlineCacheValid()) {
543 pixelSelection->recalculateOutlineCache();
544 }
545
546 QPainterPath outline = pixelSelection->outlineCache();
547 QColor color = params.color.toQColor();
548
550 if (!currentNode->inherits("KisShapeLayer") && currentNode->paintDevice()) {
553 KisToolShapeUtils::FillStyle fillStyle = params.fillStyle();
554
555 KisFigurePaintingToolHelper helper(kundo2_i18n("Draw Polyline"),
556 image,
557 currentNode,
558 rManager ,
559 strokeStyle,
560 fillStyle);
561 helper.setFGColorOverride(params.color);
562 helper.setSelectionOverride(0);
563 QPen pen(Qt::red, size);
564 pen.setJoinStyle(Qt::RoundJoin);
565
566 if (fillStyle != KisToolShapeUtils::FillStyleNone) {
567 helper.paintPainterPathQPenFill(outline, pen, params.fillColor);
568 }
569 else {
570 helper.paintPainterPathQPen(outline, pen, params.fillColor);
571 }
572 }
573 else if (currentNode->inherits("KisShapeLayer")) {
574
575 QTransform transform = view->canvasBase()->coordinatesConverter()->imageToDocumentTransform();
576
577 KoShape *shape = KoPathShape::createShapeFromPainterPath(transform.map(outline));
579
580 KoShapeStrokeSP border(new KoShapeStroke(size, color));
581 shape->setStroke(border);
582
583 KUndo2Command *cmd = view->canvasBase()->shapeController()->addShapeDirect(shape, 0);
585 }
586}
587
589{
590 KisImageWSP image = view->image();
591 if (!image) {
592 return;
593 }
594
595 KisSelectionSP selection = view->selection();
596 if (!selection) {
597 return;
598 }
599
600 KisPixelSelectionSP pixelSelection = selection->projection();
601 if (!pixelSelection->outlineCacheValid()) {
602 pixelSelection->recalculateOutlineCache();
603 }
604
606 if (!currentNode->inherits("KisShapeLayer") && currentNode->paintDevice())
607 {
609 QPainterPath outline = pixelSelection->outlineCache();
612 KoColor color = params.color;
613
614 KisFigurePaintingToolHelper helper(kundo2_i18n("Draw Polyline"),
615 image,
616 currentNode,
617 rManager,
618 strokeStyle,
619 fillStyle);
620 helper.setFGColorOverride(color);
621 helper.setSelectionOverride(0);
622 helper.paintPainterPath(outline);
623 }
624}
const quint8 OPACITY_OPAQUE_U8
#define KoPathShapeId
Definition KoPathShape.h:20
void setOutDirtyRect(QSharedPointer< QRect > outDirtyRect)
void setSeedPoint(const QPoint &seedPoint)
void setSelectionOnly(bool selectionOnly)
void setUseBgColor(bool useBgColor)
void setUsePattern(bool usePattern)
KUndo2MagicString text() const
KisCoordinatesConverter * coordinatesConverter
KoShapeManager shapeManager
KisToolProxy toolProxy
KoCanvasResourceProvider * resourceManager()
static KisClipboard * instance()
void setLayers(KisNodeList nodes, KisImageSP image, const QRect referenceRect, bool forceCopy=false)
void paintPainterPathQPenFill(const QPainterPath, const QPen &pen, const KoColor &color)
void setSelectionOverride(KisSelectionSP m_selection)
void paintPainterPath(const QPainterPath &path)
void paintPainterPathQPen(const QPainterPath, const QPen &pen, const KoColor &color)
void unlock()
Definition kis_image.cc:831
void barrierLock(bool readOnly=false)
Wait until all the queued background jobs are completed and lock the image.
Definition kis_image.cc:782
void addJob(KisStrokeId id, KisStrokeJobData *data) override
void cropImage(const QRect &newRect)
start asynchronous operation on cropping the image
Definition kis_image.cc:896
KisStrokeId startStroke(KisStrokeStrategy *strokeStrategy) override
KisSelectionSP globalSelection() const
Definition kis_image.cc:721
QRect bounds() const override
void addSpontaneousJob(KisSpontaneousJob *spontaneousJob)
void endStroke(KisStrokeId id) override
KisNodeList selectedNodes()
void endAction(KisProcessingApplicator *applicator, const QString &xmlData)
KisProcessingApplicator * beginAction(KisViewManager *view, const KUndo2MagicString &actionName, Flags flags=Normal)
void clearSelection(KisSelectionSP selection)
static void runSingleCommandStroke(KisImageSP image, KUndo2Command *cmd, KisStrokeJobData::Sequentiality sequentiality=KisStrokeJobData::SEQUENTIAL, KisStrokeJobData::Exclusivity exclusivity=KisStrokeJobData::NORMAL)
runSingleCommandStroke creates a stroke and runs cmd in it. The text() field of cmd is used as a titl...
void applyCommand(KUndo2Command *command, KisStrokeJobData::Sequentiality sequentiality=KisStrokeJobData::SEQUENTIAL, KisStrokeJobData::Exclusivity exclusivity=KisStrokeJobData::NORMAL)
The KisResourcesSnapshot class takes a snapshot of the various resources like colors and settings use...
void addSelectionShapes(QList< KoShape * > shapes, SelectionAction action=SELECTION_DEFAULT)
KUndo2Command * endAndTake()
bool blockUntilOperationsFinished(KisImageSP image)
blockUntilOperationsFinished blocks the GUI of the application until execution of actions on image is...
KisCanvas2 * canvasBase() const
Return the canvas base class.
KisNodeSP activeNode()
KisSelectionSP selection()
KisNodeManager * nodeManager() const
The node manager handles everything about nodes.
KisSelectionManager * selectionManager()
KisImageWSP image() const
Return the image this view is displaying.
KisCanvasResourceProvider * canvasResourceProvider()
void showFloatingMessage(const QString &message, const QIcon &icon, int timeout=4500, KisFloatingMessage::Priority priority=KisFloatingMessage::Medium, int alignment=Qt::AlignCenter|Qt::TextWordWrap)
shows a floating message in the top right corner of the canvas
QPointer< KoShapeController > shapeController
QPointer< KoCanvasResourceProvider > resourceManager
void toQColor(QColor *c) const
a convenience method for the above.
Definition KoColor.cpp:198
static KoPathShape * createShapeFromPainterPath(const QPainterPath &path)
Creates path shape from given QPainterPath.
const QList< KoShape * > selectedShapes() const
KoSelection * selection
KoShapeUserData * userData() const
Definition KoShape.cpp:625
KoShape * cloneShapeAndBakeAbsoluteTransform() const
creates a deep copy of the shape/shapes tree and bakes the absolute transform of this into the result...
Definition KoShape.cpp:180
virtual void setStroke(KoShapeStrokeModelSP stroke)
Definition KoShape.cpp:899
void setUserData(KoShapeUserData *userData)
Definition KoShape.cpp:620
void setShapeId(const QString &id)
Definition KoShape.cpp:880
void copy() const
Forwarded to the current KoToolBase.
void deselect()
Forwarded to the current KoToolBase.
void cut()
Forwarded to the current KoToolBase.
bool hasSelection() const
returns true if the current tool holds a selection
void deleteSelection()
Forwarded to the current KoToolBase.
bool selectAll()
Forwarded to the current KoToolBase.
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:128
QSharedPointer< KUndo2Command > KUndo2CommandSP
Definition kis_types.h:262
KUndo2MagicString kundo2_i18n(const char *text)
KisNodeList sortAndFilterMergeableInternalNodes(KisNodeList nodes, bool allowMasks)
void recursiveApplyNodes(NodePointer node, Functor func)
KisImageSP buildImageForClipboard(KisImageSP srcImage, KisNodeList nodes)
void trimDeviceForClipboard(KisImageSP image, KisPaintDeviceSP device, KisSelectionSP selection, bool makeSharpClip)
@ ForegroundColor
The active foreground color selected for this canvas.
virtual KisPaintDeviceSP projection() const =0
bool isAnimated() const
virtual KisPaintDeviceSP paintDevice() const =0
QString name() const
quint8 opacity() const
bool hasEditablePaintDevice() const
void run(KisViewManager *view) override
The LambdaCommand struct is a shorthand for creation of AggregateCommand commands using C++ lambda fe...
void run(KisViewManager *view) override
void run(Flags flags, KisViewManager *view)
void run(KisViewManager *view) override
void run(const QString &fillSource, KisViewManager *view)
void runFilter(KisSelectionFilter *filter, KisViewManager *view, const KisOperationConfiguration &config)
void runFromXML(KisViewManager *view, const KisOperationConfiguration &config) override
virtual KisNodeSP clone() const =0
virtual void setDirty()
Definition kis_node.cpp:577
void recalculateOutlineCache() override
void clear(const QRect &r)
void select(const QRect &r, quint8 selectedness=MAX_SELECTED)
void toXML(QDomDocument &, QDomElement &) const override
virtual void setProperty(const QString &name, const QVariant &value)
void run(KisViewManager *view) override
void run(KisViewManager *view) override
void run(KisViewManager *view) override
KisPixelSelectionSP projection() const
bool outlineCacheValid() const
KisPixelSelectionSP pixelSelection
QRect selectedRect() const
bool hasShapeSelection() const
QRect selectedExactRect() const
Slow, but exact way of determining the rectangle that encloses the selection.
QPainterPath outlineCache() const
void run(KisViewManager *view, const StrokeSelectionOptions &params)
void run(KisViewManager *view, const StrokeSelectionOptions &params)
KisToolShapeUtils::FillStyle fillStyle() const