Krita Source Code Documentation
Loading...
Searching...
No Matches
DefaultTool Class Reference

#include <DefaultTool.h>

+ Inheritance diagram for DefaultTool:

Classes

class  MoveGradientHandleInteractionFactory
 
class  MoveMeshGradientHandleInteractionFactory
 

Public Types

enum  CanvasResource { HotPosition = 1410100299 }
 

Public Slots

void activate (const QSet< KoShape * > &shapes) override
 
void deactivate () override
 
- Public Slots inherited from KoToolBase
virtual void activate (const QSet< KoShape * > &shapes)
 
virtual void deactivate ()
 
virtual void documentResourceChanged (int key, const QVariant &res)
 
virtual void repaintDecorations ()
 
virtual void requestRedoDuringStroke ()
 
virtual void requestStrokeCancellation ()
 
virtual void requestStrokeEnd ()
 
virtual void requestUndoDuringStroke ()
 
void setStatusText (const QString &statusText)
 
void updateOptionsWidgetIcons ()
 

Signals

void meshgradientHandleSelected (KoShapeMeshGradientHandles::Handle)
 
- Signals inherited from KoToolBase
void activateTool (const QString &id)
 
void cursorChanged (const QCursor &cursor)
 
void selectionChanged (bool hasSelection)
 
void statusTextChanged (const QString &statusText)
 
void textModeChanged (bool inTextMode)
 

Public Member Functions

void copy () const override
 reimplemented
 
QRectF decorationsRect () const override
 
 DefaultTool (KoCanvasBase *canvas, bool connectToSelectedShapesProxy=false)
 
void deleteSelection () override
 reimplemented
 
void deselect () override
 reimplemented
 
void explicitUserStrokeEndRequest () override
 explicitUserStrokeEndRequest is called by the input manager when the user presses Enter key or any equivalent. This callback comes before requestStrokeEnd(), which comes from a different source.
 
KoFlake::SelectionHandle handleAt (const QPointF &point, bool *innerHandleMeaning=0)
 
void keyPressEvent (QKeyEvent *event) override
 
void mouseDoubleClickEvent (KoPointerEvent *event) override
 
void mouseMoveEvent (KoPointerEvent *event) override
 
void mousePressEvent (KoPointerEvent *event) override
 
void mouseReleaseEvent (KoPointerEvent *event) override
 
void paint (QPainter &painter, const KoViewConverter &converter) override
 
bool paste () override
 reimplemented
 
QMenu * popupActionsMenu () override
 
bool selectAll () override
 reimplemented
 
KoToolSelectionselection () override
 reimplemented
 
bool wantsAutoScroll () const override
 
 ~DefaultTool () override
 
- Public Member Functions inherited from KoInteractionTool
void keyPressEvent (QKeyEvent *event) override
 
void keyReleaseEvent (QKeyEvent *event) override
 
 KoInteractionTool (KoCanvasBase *canvas)
 
void mouseMoveEvent (KoPointerEvent *event) override
 
void mousePressEvent (KoPointerEvent *event) override
 
void mouseReleaseEvent (KoPointerEvent *event) override
 
void paint (QPainter &painter, const KoViewConverter &converter) override
 
 ~KoInteractionTool () override
 
- Public Member Functions inherited from KoToolBase
QAction * action (const QString &name) const
 
KoCanvasBasecanvas () const
 Returns the canvas the tool is working on.
 
QCursor cursor () const
 return the last emitted cursor
 
virtual void customMoveEvent (KoPointerEvent *event)
 
virtual void customPressEvent (KoPointerEvent *event)
 
virtual void customReleaseEvent (KoPointerEvent *event)
 
virtual void cut ()
 
int decorationThickness () const
 decorationThickness The minimum thickness for tool decoration lines, this is derived from the screen magnification, thus the HiDPI settings. Note: to use this effectively, also set the pen to isCosmetic(true);
 
virtual void dragLeaveEvent (QDragLeaveEvent *event)
 
virtual void dragMoveEvent (QDragMoveEvent *event, const QPointF &point)
 
virtual void dropEvent (QDropEvent *event, const QPointF &point)
 
KoToolFactoryBasefactory () const
 
virtual void focusInEvent (QFocusEvent *event)
 
virtual void focusOutEvent (QFocusEvent *event)
 
virtual bool hasSelection ()
 
virtual void inputMethodEvent (QInputMethodEvent *event)
 
virtual QVariant inputMethodQuery (Qt::InputMethodQuery query) const
 
bool isInTextMode () const
 
bool isOpacityPresetMode () const
 
 KoToolBase (KoCanvasBase *canvas)
 
bool maskSyntheticEvents () const
 
virtual void mouseTripleClickEvent (KoPointerEvent *event)
 
QList< QPointer< QWidget > > optionWidgets ()
 
virtual KisPopupWidgetInterfacepopupWidget ()
 
Q_INVOKABLE QString toolId () const
 
 ~KoToolBase () override
 

Protected Slots

void updateActions ()
 Update actions on selection change.
 

Protected Member Functions

void addTransformActions (QMenu *menu) const
 
QList< QPointer< QWidget > > createOptionWidgets () override
 
KoInteractionStrategycreateStrategy (KoPointerEvent *event) override
 
virtual bool isValidForCurrentLayer () const
 
virtual KoSelectionkoSelection () const
 
virtual KoShapeManagershapeManager () const
 
virtual void updateDistinctiveActions (const QList< KoShape * > &editableShapes)
 
- Protected Member Functions inherited from KoInteractionTool
void addInteractionFactory (KoInteractionStrategyFactory *factory)
 
void cancelCurrentStrategy ()
 Cancels the current strategy and deletes it.
 
KoInteractionStrategycreateStrategyBase (KoPointerEvent *event)
 
KoInteractionStrategycurrentStrategy ()
 
bool hasInteractionFactory (const QString &id)
 
 KoInteractionTool (KoInteractionToolPrivate &dd)
 
void removeInteractionFactory (const QString &id)
 
bool tryUseCustomCursor ()
 
- Protected Member Functions inherited from KoToolBase
virtual QWidget * createOptionWidget ()
 
int grabSensitivity () const
 Convenience function to get the current grab sensitivity.
 
qreal handleDocRadius () const
 
QRectF handleGrabRect (const QPointF &position) const
 
QRectF handlePaintRect (const QPointF &position) const
 
int handleRadius () const
 Convenience function to get the current handle radius.
 
bool isActivated () const
 
 KoToolBase (KoToolBasePrivate &dd)
 
KoPointerEventlastDeliveredPointerEvent () const
 
void setAbstractResource (KoAbstractCanvasResourceInterfaceSP abstractResource)
 
void setConverter (KoDerivedResourceConverterSP converter)
 
void setIsOpacityPresetMode (bool value)
 
void setMaskSyntheticEvents (bool value)
 
void setTextMode (bool value)
 
QHash< int, KoAbstractCanvasResourceInterfaceSPtoolAbstractResources ()
 
QHash< int, KoDerivedResourceConverterSPtoolConverters ()
 
void useCursor (const QCursor &cursor)
 

Protected Attributes

QScopedPointer< QMenu > m_contextMenu
 
- Protected Attributes inherited from KoToolBase
KoToolBasePrivated_ptr
 

Private Slots

void selectionAlign (int _align)
 
void selectionBooleanOp (int booleanOp)
 
void selectionBringToFront ()
 
void selectionDistribute (int _distribute)
 
void selectionGroup ()
 
void selectionMoveDown ()
 
void selectionMoveUp ()
 
void selectionSendToBack ()
 
void selectionSplitShapes ()
 
void selectionTransform (int transformAction)
 
void selectionUngroup ()
 
void slotActivateEditFillGradient (bool value)
 
void slotActivateEditFillMeshGradient (bool value)
 
void slotActivateEditStrokeGradient (bool value)
 
void slotChangeTextType (int index)
 
void slotResetMeshGradientState ()
 

Private Member Functions

void addMappedAction (KisSignalMapper *mapper, const QString &actionId, int type)
 
void canvasResourceChanged (int key, const QVariant &res) override
 
QRectF handlesSize ()
 Returns selection rectangle adjusted by handle proximity threshold.
 
bool moveSelection (int direction, Qt::KeyboardModifiers modifiers)
 
void recalcSelectionBox (KoSelection *selection)
 
qreal rotationOfHandle (KoFlake::SelectionHandle handle, bool useEdgeRotation)
 Returns rotation angle of given handle of the current selection.
 
void selectionReorder (KoShapeReorderCommand::MoveShapeType order)
 
void setupActions ()
 
void updateCursor ()
 

Private Attributes

KisSignalMapperm_alignSignalsMapper {0}
 
qreal m_angle
 
KisSignalMapperm_booleanSignalsMapper {0}
 
QScopedPointer< SelectionDecoratorm_decorator
 
KisSignalMapperm_distributeSignalsMapper {0}
 
KoFlake::AnchorPosition m_hotPosition
 
KoShapeMeshGradientHandles::Handle m_hoveredMeshHandle
 
KoFlake::SelectionHandle m_lastHandle
 
QPointF m_lastPoint
 
bool m_mouseWasInsideHandles
 
QCursor m_rotateCursors [8]
 
KoShapeMeshGradientHandles::Handle m_selectedMeshHandle
 
QPointF m_selectionBox [8]
 
KoToolSelectionm_selectionHandler
 
QPolygonF m_selectionOutline
 
QCursor m_shearCursors [8]
 
QCursor m_sizeCursors [8]
 
DefaultToolTabbedWidgetm_tabbedOptionWidget
 
DefaultToolTextPropertiesInterfacem_textPropertyInterface {0}
 
KisSignalMapperm_textTypeSignalsMapper {0}
 
KisSignalMapperm_transformSignalsMapper {0}
 

Friends

class SelectionHandler
 
class SelectionInteractionStrategy
 

Detailed Description

The default tool (associated with the arrow icon) implements the default interactions you have with flake objects.
The tool provides scaling, moving, selecting, rotation and soon skewing of any number of shapes.

Note that the implementation of those different strategies are delegated to the InteractionStrategy class and its subclasses.

Definition at line 40 of file DefaultTool.h.

Member Enumeration Documentation

◆ CanvasResource

Enumerator
HotPosition 

Definition at line 52 of file DefaultTool.h.

52 {
53 HotPosition = 1410100299
54 };

Constructor & Destructor Documentation

◆ DefaultTool()

DefaultTool::DefaultTool ( KoCanvasBase * canvas,
bool connectToSelectedShapesProxy = false )
explicit

Constructor for basic interaction tool where user actions are translated and handled by interaction strategies of type KoInteractionStrategy.

Parameters
canvasthe canvas this tool will be working for.

Definition at line 415 of file DefaultTool.cpp.

423{
424 setupActions();
425
426 QPixmap rotatePixmap, shearPixmap;
427 rotatePixmap.load(":/cursor_rotate.png");
428 Q_ASSERT(!rotatePixmap.isNull());
429 shearPixmap.load(":/cursor_shear.png");
430 Q_ASSERT(!shearPixmap.isNull());
431
432 m_rotateCursors[0] = QCursor(rotatePixmap.transformed(QTransform().rotate(45)));
433 m_rotateCursors[1] = QCursor(rotatePixmap.transformed(QTransform().rotate(90)));
434 m_rotateCursors[2] = QCursor(rotatePixmap.transformed(QTransform().rotate(135)));
435 m_rotateCursors[3] = QCursor(rotatePixmap.transformed(QTransform().rotate(180)));
436 m_rotateCursors[4] = QCursor(rotatePixmap.transformed(QTransform().rotate(225)));
437 m_rotateCursors[5] = QCursor(rotatePixmap.transformed(QTransform().rotate(270)));
438 m_rotateCursors[6] = QCursor(rotatePixmap.transformed(QTransform().rotate(315)));
439 m_rotateCursors[7] = QCursor(rotatePixmap);
440 /*
441 m_rotateCursors[0] = QCursor(Qt::RotateNCursor);
442 m_rotateCursors[1] = QCursor(Qt::RotateNECursor);
443 m_rotateCursors[2] = QCursor(Qt::RotateECursor);
444 m_rotateCursors[3] = QCursor(Qt::RotateSECursor);
445 m_rotateCursors[4] = QCursor(Qt::RotateSCursor);
446 m_rotateCursors[5] = QCursor(Qt::RotateSWCursor);
447 m_rotateCursors[6] = QCursor(Qt::RotateWCursor);
448 m_rotateCursors[7] = QCursor(Qt::RotateNWCursor);
449 */
450 m_shearCursors[0] = QCursor(shearPixmap);
451 m_shearCursors[1] = QCursor(shearPixmap.transformed(QTransform().rotate(45)));
452 m_shearCursors[2] = QCursor(shearPixmap.transformed(QTransform().rotate(90)));
453 m_shearCursors[3] = QCursor(shearPixmap.transformed(QTransform().rotate(135)));
454 m_shearCursors[4] = QCursor(shearPixmap.transformed(QTransform().rotate(180)));
455 m_shearCursors[5] = QCursor(shearPixmap.transformed(QTransform().rotate(225)));
456 m_shearCursors[6] = QCursor(shearPixmap.transformed(QTransform().rotate(270)));
457 m_shearCursors[7] = QCursor(shearPixmap.transformed(QTransform().rotate(315)));
458 m_sizeCursors[0] = Qt::SizeVerCursor;
459 m_sizeCursors[1] = Qt::SizeBDiagCursor;
460 m_sizeCursors[2] = Qt::SizeHorCursor;
461 m_sizeCursors[3] = Qt::SizeFDiagCursor;
462 m_sizeCursors[4] = Qt::SizeVerCursor;
463 m_sizeCursors[5] = Qt::SizeBDiagCursor;
464 m_sizeCursors[6] = Qt::SizeHorCursor;
465 m_sizeCursors[7] = Qt::SizeFDiagCursor;
466
467 if (connectToSelectedShapesProxy) {
469
471 connect(canvas->selectedShapesProxy(), SIGNAL(selectionChanged()), m_textPropertyInterface, SLOT(slotSelectionChanged()));
472 connect(canvas->selectedShapesProxy(), SIGNAL(selectionContentChanged()), this, SLOT(repaintDecorations()));
473 }
474}
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
KoFlake::SelectionHandle m_lastHandle
bool m_mouseWasInsideHandles
KoFlake::AnchorPosition m_hotPosition
void updateActions()
Update actions on selection change.
QCursor m_shearCursors[8]
QCursor m_sizeCursors[8]
DefaultToolTabbedWidget * m_tabbedOptionWidget
friend class SelectionHandler
DefaultToolTextPropertiesInterface * m_textPropertyInterface
QCursor m_rotateCursors[8]
void setupActions()
KoToolSelection * m_selectionHandler
virtual KoSelectedShapesProxy * selectedShapesProxy() const =0
selectedShapesProxy() is a special interface for keeping a persistent connections to selectionChanged...
KoInteractionTool(KoCanvasBase *canvas)
KoCanvasBase * canvas() const
Returns the canvas the tool is working on.
void selectionChanged(bool hasSelection)
virtual void repaintDecorations()
@ TopLeft
Definition KoFlake.h:86
@ NoHandle
Value to indicate no handle.
Definition KoFlake.h:64
Interface to interact with the text property manager.

References KoToolBase::canvas(), connect(), m_rotateCursors, m_shearCursors, m_sizeCursors, m_textPropertyInterface, KoToolBase::repaintDecorations(), KoCanvasBase::selectedShapesProxy(), KoToolBase::selectionChanged(), setupActions(), and updateActions().

◆ ~DefaultTool()

DefaultTool::~DefaultTool ( )
override

Definition at line 476 of file DefaultTool.cpp.

477{
478}

Member Function Documentation

◆ activate

void DefaultTool::activate ( const QSet< KoShape * > & shapes)
overrideslot

Definition at line 1201 of file DefaultTool.cpp.

1202{
1203 KoToolBase::activate(shapes);
1204
1205 QAction *actionBringToFront = action("object_order_front");
1206 connect(actionBringToFront, SIGNAL(triggered()), this, SLOT(selectionBringToFront()), Qt::UniqueConnection);
1207
1208 QAction *actionRaise = action("object_order_raise");
1209 connect(actionRaise, SIGNAL(triggered()), this, SLOT(selectionMoveUp()), Qt::UniqueConnection);
1210
1211 QAction *actionLower = action("object_order_lower");
1212 connect(actionLower, SIGNAL(triggered()), this, SLOT(selectionMoveDown()));
1213
1214 QAction *actionSendToBack = action("object_order_back");
1215 connect(actionSendToBack, SIGNAL(triggered()), this, SLOT(selectionSendToBack()), Qt::UniqueConnection);
1216
1217 QAction *actionGroupBottom = action("object_group");
1218 connect(actionGroupBottom, SIGNAL(triggered()), this, SLOT(selectionGroup()), Qt::UniqueConnection);
1219
1220 QAction *actionUngroupBottom = action("object_ungroup");
1221 connect(actionUngroupBottom, SIGNAL(triggered()), this, SLOT(selectionUngroup()), Qt::UniqueConnection);
1222
1223 QAction *actionSplit = action("object_split");
1224 connect(actionSplit, SIGNAL(triggered()), this, SLOT(selectionSplitShapes()), Qt::UniqueConnection);
1225
1226 connect(m_alignSignalsMapper, SIGNAL(mapped(int)), SLOT(selectionAlign(int)));
1227 connect(m_distributeSignalsMapper, SIGNAL(mapped(int)), SLOT(selectionDistribute(int)));
1228 connect(m_transformSignalsMapper, SIGNAL(mapped(int)), SLOT(selectionTransform(int)));
1229 connect(m_booleanSignalsMapper, SIGNAL(mapped(int)), SLOT(selectionBooleanOp(int)));
1230 connect(m_textTypeSignalsMapper, SIGNAL(mapped(int)), SLOT(slotChangeTextType(int)));
1231
1234 useCursor(Qt::ArrowCursor);
1236 updateActions();
1237
1238 const KisCanvas2 *canvas2 = qobject_cast<const KisCanvas2 *>(this->canvas());
1239 if (canvas2) {
1242 }
1243
1246 }
1247}
void selectionSendToBack()
KisSignalMapper * m_textTypeSignalsMapper
void selectionDistribute(int _distribute)
KisSignalMapper * m_booleanSignalsMapper
KisSignalMapper * m_distributeSignalsMapper
void selectionTransform(int transformAction)
void selectionGroup()
void selectionAlign(int _align)
void selectionMoveDown()
void selectionBooleanOp(int booleanOp)
KisSignalMapper * m_alignSignalsMapper
KisSignalMapper * m_transformSignalsMapper
void selectionBringToFront()
void selectionUngroup()
void slotChangeTextType(int index)
void selectionSplitShapes()
void selectionMoveUp()
KisViewManager * viewManager() const
void setTextPropertiesInterface(KoSvgTextPropertiesInterface *interface)
setTextPropertiesInterface set the text properties interface. This should be done on tool activation....
KisTextPropertiesManager * textPropertyManager() const
void useCursor(const QCursor &cursor)
virtual void activate(const QSet< KoShape * > &shapes)
QAction * action(const QString &name) const

References KoToolBase::action(), DefaultToolTabbedWidget::activate(), KoToolBase::activate(), KoToolBase::canvas(), connect(), m_alignSignalsMapper, m_booleanSignalsMapper, m_distributeSignalsMapper, m_lastHandle, m_mouseWasInsideHandles, m_tabbedOptionWidget, m_textPropertyInterface, m_textTypeSignalsMapper, m_transformSignalsMapper, KoFlake::NoHandle, KoToolBase::repaintDecorations(), selectionAlign(), selectionBooleanOp(), selectionBringToFront(), selectionDistribute(), selectionGroup(), selectionMoveDown(), selectionMoveUp(), selectionSendToBack(), selectionSplitShapes(), selectionTransform(), selectionUngroup(), KisTextPropertiesManager::setTextPropertiesInterface(), slotChangeTextType(), DefaultToolTextPropertiesInterface::slotSelectionChanged(), KisViewManager::textPropertyManager(), updateActions(), KoToolBase::useCursor(), and KisCanvas2::viewManager().

◆ addMappedAction()

void DefaultTool::addMappedAction ( KisSignalMapper * mapper,
const QString & actionId,
int type )
private

Definition at line 556 of file DefaultTool.cpp.

557{
558 QAction *a =action(actionId);
559 connect(a, SIGNAL(triggered()), mapper, SLOT(map()));
560 mapper->setMapping(a, commandType);
561}
void setMapping(QObject *sender, int id)

References KoToolBase::action(), connect(), and KisSignalMapper::setMapping().

◆ addTransformActions()

void DefaultTool::addTransformActions ( QMenu * menu) const
protected

Definition at line 1971 of file DefaultTool.cpp.

1971 {
1972 menu->addAction(action("object_transform_rotate_90_cw"));
1973 menu->addAction(action("object_transform_rotate_90_ccw"));
1974 menu->addAction(action("object_transform_rotate_180"));
1975 menu->addSeparator();
1976 menu->addAction(action("object_transform_mirror_horizontally"));
1977 menu->addAction(action("object_transform_mirror_vertically"));
1978 menu->addSeparator();
1979 menu->addAction(action("object_transform_reset"));
1980}

References KoToolBase::action().

◆ canvasResourceChanged()

void DefaultTool::canvasResourceChanged ( int key,
const QVariant & res )
overrideprivatevirtual

This method is called whenever a property in the resource provider associated with the canvas this tool belongs to changes. An example is currently selected foreground color.

Reimplemented from KoToolBase.

Definition at line 1674 of file DefaultTool.cpp.

1675{
1676 if (key == HotPosition) {
1679 }
1680}
AnchorPosition
Definition KoFlake.h:85

References HotPosition, m_hotPosition, and KoToolBase::repaintDecorations().

◆ copy()

void DefaultTool::copy ( ) const
overridevirtual

reimplemented

Reimplemented from KoToolBase.

Definition at line 1053 of file DefaultTool.cpp.

1054{
1055 // all the selected shapes, not only editable!
1057
1058 if (!shapes.isEmpty()) {
1059 KoDrag drag;
1060 drag.setSvg(shapes);
1061 drag.addToClipboard();
1062 }
1063}
virtual KoSelection * koSelection() const
bool setSvg(const QList< KoShape * > shapes)
Definition KoDrag.cpp:47
void addToClipboard()
Definition KoDrag.cpp:86
const QList< KoShape * > selectedShapes() const

References KoDrag::addToClipboard(), koSelection(), KoSelection::selectedShapes(), and KoDrag::setSvg().

◆ createOptionWidgets()

QList< QPointer< QWidget > > DefaultTool::createOptionWidgets ( )
overrideprotectedvirtual

Reimplemented from KoToolBase.

Reimplemented in ToolReferenceImages.

Definition at line 1643 of file DefaultTool.cpp.

1644{
1645 QList<QPointer<QWidget> > widgets;
1646
1648
1649 if (isActivated()) {
1651 }
1652 widgets.append(m_tabbedOptionWidget);
1653
1655 SIGNAL(sigSwitchModeEditFillGradient(bool)),
1656 SLOT(slotActivateEditFillGradient(bool)));
1657
1659 SIGNAL(sigSwitchModeEditStrokeGradient(bool)),
1660 SLOT(slotActivateEditStrokeGradient(bool)));
1661
1663 SIGNAL(sigSwitchModeEditFillGradient(bool)),
1665 // TODO: strokes!!
1666
1668 SIGNAL(sigMeshGradientResetted()),
1670
1671 return widgets;
1672}
void slotActivateEditStrokeGradient(bool value)
void slotActivateEditFillMeshGradient(bool value)
void slotActivateEditFillGradient(bool value)
void slotResetMeshGradientState()
bool isActivated() const

References DefaultToolTabbedWidget::activate(), connect(), KoToolBase::isActivated(), m_tabbedOptionWidget, slotActivateEditFillGradient(), slotActivateEditFillMeshGradient(), slotActivateEditStrokeGradient(), and slotResetMeshGradientState().

◆ createStrategy()

KoInteractionStrategy * DefaultTool::createStrategy ( KoPointerEvent * event)
overrideprotectedvirtual

Implements KoInteractionTool.

Definition at line 1682 of file DefaultTool.cpp.

1683{
1685 if (!selection) return nullptr;
1686
1687 bool insideSelection = false;
1688 KoFlake::SelectionHandle handle = handleAt(event->point, &insideSelection);
1689
1690 bool editableShape = !selection->selectedEditableShapes().isEmpty();
1691
1692 const bool selectMultiple = event->modifiers() & Qt::ShiftModifier;
1693 const bool selectNextInStack = event->modifiers() & Qt::ControlModifier;
1694 const bool avoidSelection = event->modifiers() & Qt::AltModifier;
1695
1696 if (selectNextInStack) {
1697 // change the hot selection position when middle clicking on a handle
1698 KoFlake::AnchorPosition newHotPosition = m_hotPosition;
1699 switch (handle) {
1701 newHotPosition = KoFlake::Top;
1702 break;
1704 newHotPosition = KoFlake::TopRight;
1705 break;
1707 newHotPosition = KoFlake::Right;
1708 break;
1710 newHotPosition = KoFlake::BottomRight;
1711 break;
1713 newHotPosition = KoFlake::Bottom;
1714 break;
1716 newHotPosition = KoFlake::BottomLeft;
1717 break;
1719 newHotPosition = KoFlake::Left;
1720 break;
1722 newHotPosition = KoFlake::TopLeft;
1723 break;
1724 case KoFlake::NoHandle:
1725 default:
1726 // check if we had hit the center point
1727 const KoViewConverter *converter = canvas()->viewConverter();
1728 QPointF pt = converter->documentToView(event->point);
1729
1730 // TODO: use calculated values instead!
1731 QPointF centerPt = converter->documentToView(selection->absolutePosition());
1732
1733 if (kisSquareDistance(pt, centerPt) < HANDLE_DISTANCE_SQ) {
1734 newHotPosition = KoFlake::Center;
1735 }
1736
1737 break;
1738 }
1739
1740 if (m_hotPosition != newHotPosition) {
1741 canvas()->resourceManager()->setResource(HotPosition, newHotPosition);
1742 return new NopInteractionStrategy(this);
1743 }
1744 }
1745
1746 if (!avoidSelection && editableShape) {
1747 // manipulation of selected shapes goes first
1748 if (handle != KoFlake::NoHandle) {
1749 // resizing or shearing only with left mouse button
1750 if (insideSelection) {
1751 bool forceUniformScaling = m_tabbedOptionWidget && m_tabbedOptionWidget->useUniformScaling();
1752 return new ShapeResizeStrategy(this, selection, event->point, handle, forceUniformScaling);
1753 }
1754
1755 if (handle == KoFlake::TopMiddleHandle || handle == KoFlake::RightMiddleHandle ||
1757
1758 return new ShapeShearStrategy(this, selection, event->point, handle);
1759 }
1760
1761 // rotating is allowed for right mouse button too
1762 if (handle == KoFlake::TopLeftHandle || handle == KoFlake::TopRightHandle ||
1764
1765 return new ShapeRotateStrategy(this, selection, event->point, event->buttons());
1766 }
1767 }
1768
1769 if (!selectMultiple && !selectNextInStack) {
1770
1771 if (insideSelection) {
1772 return new ShapeMoveStrategy(this, selection, event->point);
1773 }
1774 }
1775 }
1776
1777 KoShape *shape = shapeManager()->shapeAt(event->point, selectNextInStack ? KoFlake::NextUnselected : KoFlake::ShapeOnTop);
1778
1779 if (avoidSelection || (!shape && handle == KoFlake::NoHandle)) {
1780 if (!selectMultiple) {
1781 selection->deselectAll();
1782 }
1783 return new SelectionInteractionStrategy(this, event->point, false);
1784 }
1785
1786 if (selection->isSelected(shape)) {
1787 if (selectMultiple) {
1788 selection->deselect(shape);
1789 }
1790 } else if (handle == KoFlake::NoHandle) { // clicked on shape which is not selected
1791 if (!selectMultiple) {
1792 selection->deselectAll();
1793 }
1794 selection->select(shape);
1795 // tablet selection isn't precise and may lead to a move, preventing that
1796 if (event->isTabletEvent()) {
1797 return new NopInteractionStrategy(this);
1798 }
1799 return new ShapeMoveStrategy(this, selection, event->point);
1800 }
1801 return 0;
1802}
#define HANDLE_DISTANCE_SQ
KoFlake::SelectionHandle handleAt(const QPointF &point, bool *innerHandleMeaning=0)
friend class SelectionInteractionStrategy
KoToolSelection * selection() override
reimplemented
virtual KoShapeManager * shapeManager() const
virtual const KoViewConverter * viewConverter() const =0
QPointer< KoCanvasResourceProvider > resourceManager
Qt::MouseButtons buttons() const
return buttons pressed (see QMouseEvent::buttons());
bool isTabletEvent() const
QPointF point
The point in document coordinates.
KoShape * shapeAt(const QPointF &position, KoFlake::ShapeSelection selection=KoFlake::ShapeOnTop, bool omitHiddenShapes=true)
virtual QPointF documentToView(const QPointF &documentPoint) const
qreal kisSquareDistance(const QPointF &pt1, const QPointF &pt2)
Definition kis_global.h:194
@ ShapeOnTop
return the shape highest z-ordering, regardless of selection.
Definition KoFlake.h:74
@ NextUnselected
return the first unselected directly under a selected shape, or the top most one if nothing is select...
Definition KoFlake.h:73
@ Left
Definition KoFlake.h:89
@ Right
Definition KoFlake.h:91
@ Bottom
Definition KoFlake.h:93
@ BottomRight
Definition KoFlake.h:94
@ Top
Definition KoFlake.h:87
@ TopRight
Definition KoFlake.h:88
@ BottomLeft
Definition KoFlake.h:92
@ Center
Definition KoFlake.h:90
SelectionHandle
Enum determining which handle is meant, used in KoInteractionTool.
Definition KoFlake.h:55
@ BottomRightHandle
The handle that is at the bottom right of a selection.
Definition KoFlake.h:59
@ BottomLeftHandle
The handle that is at the bottom left of a selection.
Definition KoFlake.h:61
@ RightMiddleHandle
The handle that is at the right - center of a selection.
Definition KoFlake.h:58
@ TopRightHandle
The handle that is at the top - right of a selection.
Definition KoFlake.h:57
@ TopLeftHandle
The handle that is at the top left of a selection.
Definition KoFlake.h:63
@ LeftMiddleHandle
The handle that is at the left center of a selection.
Definition KoFlake.h:62
@ TopMiddleHandle
The handle that is at the top - center of a selection.
Definition KoFlake.h:56
@ BottomMiddleHandle
The handle that is at the bottom center of a selection.
Definition KoFlake.h:60

References KoFlake::Bottom, KoFlake::BottomLeft, KoFlake::BottomLeftHandle, KoFlake::BottomMiddleHandle, KoFlake::BottomRight, KoFlake::BottomRightHandle, KoPointerEvent::buttons(), KoToolBase::canvas(), KoFlake::Center, KoViewConverter::documentToView(), HANDLE_DISTANCE_SQ, handleAt(), HotPosition, KoPointerEvent::isTabletEvent(), kisSquareDistance(), koSelection(), KoFlake::Left, KoFlake::LeftMiddleHandle, m_hotPosition, m_tabbedOptionWidget, KoFlake::NextUnselected, KoFlake::NoHandle, KoPointerEvent::point, KoCanvasBase::resourceManager, KoFlake::Right, KoFlake::RightMiddleHandle, selection(), SelectionInteractionStrategy, KoShapeManager::shapeAt(), shapeManager(), KoFlake::ShapeOnTop, KoFlake::Top, KoFlake::TopLeft, KoFlake::TopLeftHandle, KoFlake::TopMiddleHandle, KoFlake::TopRight, KoFlake::TopRightHandle, DefaultToolTabbedWidget::useUniformScaling(), and KoCanvasBase::viewConverter().

◆ deactivate

void DefaultTool::deactivate ( )
overrideslot

Definition at line 1249 of file DefaultTool.cpp.

1250{
1252
1253 QAction *actionBringToFront = action("object_order_front");
1254 disconnect(actionBringToFront, 0, this, 0);
1255
1256 QAction *actionRaise = action("object_order_raise");
1257 disconnect(actionRaise, 0, this, 0);
1258
1259 QAction *actionLower = action("object_order_lower");
1260 disconnect(actionLower, 0, this, 0);
1261
1262 QAction *actionSendToBack = action("object_order_back");
1263 disconnect(actionSendToBack, 0, this, 0);
1264
1265 QAction *actionGroupBottom = action("object_group");
1266 disconnect(actionGroupBottom, 0, this, 0);
1267
1268 QAction *actionUngroupBottom = action("object_ungroup");
1269 disconnect(actionUngroupBottom, 0, this, 0);
1270
1271 QAction *actionSplit = action("object_split");
1272 disconnect(actionSplit, 0, this, 0);
1273
1274 disconnect(m_alignSignalsMapper, 0, this, 0);
1275 disconnect(m_distributeSignalsMapper, 0, this, 0);
1276 disconnect(m_transformSignalsMapper, 0, this, 0);
1277 disconnect(m_booleanSignalsMapper, 0, this, 0);
1278 disconnect(m_textTypeSignalsMapper, 0, this, 0);
1279
1280 const KisCanvas2 *canvas2 = qobject_cast<const KisCanvas2 *>(this->canvas());
1281 if (canvas2) {
1284 }
1285
1288 }
1289}
virtual void deactivate()

References KoToolBase::action(), KoToolBase::canvas(), DefaultToolTextPropertiesInterface::clearSelection(), KoToolBase::deactivate(), DefaultToolTabbedWidget::deactivate(), m_alignSignalsMapper, m_booleanSignalsMapper, m_distributeSignalsMapper, m_tabbedOptionWidget, m_textPropertyInterface, m_textTypeSignalsMapper, m_transformSignalsMapper, KisTextPropertiesManager::setTextPropertiesInterface(), KisViewManager::textPropertyManager(), and KisCanvas2::viewManager().

◆ decorationsRect()

QRectF DefaultTool::decorationsRect ( ) const
overridevirtual

TODO: avoid cons_cast by implementing proper caching strategy inrecalcSelectionBox() and handlesSize()

Reimplemented from KoToolBase.

Definition at line 1035 of file DefaultTool.cpp.

1036{
1037 QRectF dirtyRect;
1038
1039 if (koSelection() && koSelection()->count() > 0) {
1043 dirtyRect = const_cast<DefaultTool*>(this)->handlesSize();
1044 }
1045
1046 if (canvas()->snapGuide()->isSnapping()) {
1047 dirtyRect |= canvas()->snapGuide()->boundingRect();
1048 }
1049
1050 return dirtyRect;
1051}
QRectF handlesSize()
Returns selection rectangle adjusted by handle proximity threshold.
KoSnapGuide * snapGuide
QRectF boundingRect()
returns the bounding rect of the guide
bool isSnapping() const
returns if snapping is enabled

References KoSnapGuide::boundingRect(), KoToolBase::canvas(), handlesSize(), KoSnapGuide::isSnapping(), koSelection(), and KoCanvasBase::snapGuide.

◆ deleteSelection()

void DefaultTool::deleteSelection ( )
overridevirtual

reimplemented

Reimplemented from KoToolBase.

Reimplemented in ToolReferenceImages.

Definition at line 1065 of file DefaultTool.cpp.

1066{
1067 QList<KoShape *> shapes;
1068 foreach (KoShape *s, koSelection()->selectedShapes()) {
1069 if (s->isGeometryProtected()) {
1070 continue;
1071 }
1072 shapes << s;
1073 }
1074 if (!shapes.empty()) {
1075 canvas()->addCommand(canvas()->shapeController()->removeShapes(shapes));
1076 }
1077}
virtual void addCommand(KUndo2Command *command)=0
bool isGeometryProtected() const
Definition KoShape.cpp:1024

References KoCanvasBase::addCommand(), KoToolBase::canvas(), KoShape::isGeometryProtected(), and koSelection().

◆ deselect()

void DefaultTool::deselect ( )
overridevirtual

reimplemented

Reimplemented from KoToolBase.

Definition at line 1098 of file DefaultTool.cpp.

1099{
1100 Q_ASSERT(canvas());
1101 Q_ASSERT(canvas()->selectedShapesProxy());
1104}
virtual KoSelection * selection()=0
void deselectAll()
clear the selections list

References KoToolBase::canvas(), KoSelection::deselectAll(), KoToolBase::repaintDecorations(), KoCanvasBase::selectedShapesProxy(), and KoSelectedShapesProxy::selection().

◆ explicitUserStrokeEndRequest()

void DefaultTool::explicitUserStrokeEndRequest ( )
overridevirtual

explicitUserStrokeEndRequest is called by the input manager when the user presses Enter key or any equivalent. This callback comes before requestStrokeEnd(), which comes from a different source.

Reimplemented from KoToolBase.

Definition at line 1982 of file DefaultTool.cpp.

1983{
1985 QString tool = KoToolManager::instance()->preferredToolForSelection(shapes);
1986 QTimer::singleShot(0, [tool = std::move(tool)]() {
1988 });
1989}
const QList< KoShape * > selectedEditableShapesAndDelegates() const
void switchToolRequested(const QString &id)
QString preferredToolForSelection(const QList< KoShape * > &shapes)
static KoToolManager * instance()
Return the toolmanager singleton.

References KoToolManager::instance(), koSelection(), KoToolManager::preferredToolForSelection(), KoSelection::selectedEditableShapesAndDelegates(), and KoToolManager::switchToolRequested().

◆ handleAt()

KoFlake::SelectionHandle DefaultTool::handleAt ( const QPointF & point,
bool * innerHandleMeaning = 0 )

Returns which selection handle is at params point (or NoHandle if none).

Returns
which selection handle is at params point (or NoHandle if none).
Parameters
pointthe location (in pt) where we should look for a handle
innerHandleMeaningthis boolean is altered to true if the point is inside the selection rectangle and false if it is just outside. The value of innerHandleMeaning is undefined if the handle location is NoHandle

Definition at line 1113 of file DefaultTool.cpp.

1114{
1115 // check for handles in this order; meaning that when handles overlap the one on top is chosen
1116 static const KoFlake::SelectionHandle handleOrder[] = {
1126 };
1127
1128 const KoViewConverter *converter = canvas()->viewConverter();
1130
1131 if (!selection || !selection->count() || !converter) {
1132 return KoFlake::NoHandle;
1133 }
1134
1136
1137 if (innerHandleMeaning) {
1138 QPainterPath path;
1139 path.addPolygon(m_selectionOutline);
1140 *innerHandleMeaning = path.contains(point) || path.intersects(handlePaintRect(point));
1141 }
1142
1143 const QPointF viewPoint = converter->documentToView(point);
1144
1145 for (int i = 0; i < KoFlake::NoHandle; ++i) {
1146 KoFlake::SelectionHandle handle = handleOrder[i];
1147
1148 const QPointF handlePoint = converter->documentToView(m_selectionBox[handle]);
1149 const qreal distanceSq = kisSquareDistance(viewPoint, handlePoint);
1150
1151 // if just inside the outline
1152 if (distanceSq < HANDLE_DISTANCE_SQ) {
1153
1154 if (innerHandleMeaning) {
1155 if (distanceSq < INNER_HANDLE_DISTANCE_SQ) {
1156 *innerHandleMeaning = true;
1157 }
1158 }
1159
1160 return handle;
1161 }
1162 }
1163 return KoFlake::NoHandle;
1164}
#define INNER_HANDLE_DISTANCE_SQ
QPointF m_selectionBox[8]
void recalcSelectionBox(KoSelection *selection)
QPolygonF m_selectionOutline
QRectF handlePaintRect(const QPointF &position) const

References KoFlake::BottomLeftHandle, KoFlake::BottomMiddleHandle, KoFlake::BottomRightHandle, KoToolBase::canvas(), KoViewConverter::documentToView(), HANDLE_DISTANCE_SQ, KoToolBase::handlePaintRect(), INNER_HANDLE_DISTANCE_SQ, kisSquareDistance(), koSelection(), KoFlake::LeftMiddleHandle, m_selectionBox, m_selectionOutline, KoFlake::NoHandle, recalcSelectionBox(), KoFlake::RightMiddleHandle, selection(), KoFlake::TopLeftHandle, KoFlake::TopMiddleHandle, KoFlake::TopRightHandle, and KoCanvasBase::viewConverter().

◆ handlesSize()

QRectF DefaultTool::handlesSize ( )
private

Returns selection rectangle adjusted by handle proximity threshold.

Definition at line 938 of file DefaultTool.cpp.

939{
941 if (!selection || !selection->count()) return QRectF();
942
944
945 QRectF bound = m_selectionOutline.boundingRect();
946
947 // expansion Border
948 if (!canvas() || !canvas()->viewConverter()) {
949 return bound;
950 }
951
952 QPointF border = canvas()->viewConverter()->viewToDocument(QPointF(HANDLE_DISTANCE, HANDLE_DISTANCE));
953 bound.adjust(-border.x(), -border.y(), border.x(), border.y());
954 return bound;
955}
#define HANDLE_DISTANCE
virtual QPointF viewToDocument(const QPointF &viewPoint) const

References KoToolBase::canvas(), HANDLE_DISTANCE, koSelection(), m_selectionOutline, recalcSelectionBox(), selection(), KoCanvasBase::viewConverter(), and KoViewConverter::viewToDocument().

◆ isValidForCurrentLayer()

bool DefaultTool::isValidForCurrentLayer ( ) const
protectedvirtual

Reimplemented in ToolReferenceImages.

Definition at line 882 of file DefaultTool.cpp.

883{
884 // if the currently active node has a shape manager, then it is
885 // probably our client :)
886
887 KisCanvas2 *kisCanvas = static_cast<KisCanvas2 *>(canvas());
888 return bool(kisCanvas->localShapeManager());
889}
KoShapeManager * localShapeManager() const

References KoToolBase::canvas(), and KisCanvas2::localShapeManager().

◆ keyPressEvent()

void DefaultTool::keyPressEvent ( QKeyEvent * event)
overridevirtual

Called when a key is pressed. Implementors should call event->ignore() if they do not actually use the event. Default implementation ignores this event.

Parameters
eventstate and reason of this key press

Reimplemented from KoToolBase.

Definition at line 1016 of file DefaultTool.cpp.

1017{
1019 if (currentStrategy() == 0) {
1020 switch (event->key()) {
1021 case Qt::Key_Left:
1022 case Qt::Key_Right:
1023 case Qt::Key_Up:
1024 case Qt::Key_Down:
1025 if (moveSelection(event->key(), event->modifiers())) {
1026 event->accept();
1027 }
1028 break;
1029 default:
1030 return;
1031 }
1032 }
1033}
bool moveSelection(int direction, Qt::KeyboardModifiers modifiers)
void keyPressEvent(QKeyEvent *event) override
KoInteractionStrategy * currentStrategy()

References KoInteractionTool::currentStrategy(), KoInteractionTool::keyPressEvent(), and moveSelection().

◆ koSelection()

KoSelection * DefaultTool::koSelection ( ) const
protectedvirtual

Reimplemented in ToolReferenceImages.

Definition at line 1106 of file DefaultTool.cpp.

1107{
1108 Q_ASSERT(canvas());
1109 Q_ASSERT(canvas()->selectedShapesProxy());
1110 return canvas()->selectedShapesProxy()->selection();
1111}

References KoToolBase::canvas(), KoCanvasBase::selectedShapesProxy(), and KoSelectedShapesProxy::selection().

◆ meshgradientHandleSelected

void DefaultTool::meshgradientHandleSelected ( KoShapeMeshGradientHandles::Handle )
signal

◆ mouseDoubleClickEvent()

void DefaultTool::mouseDoubleClickEvent ( KoPointerEvent * event)
overridevirtual

Called when (one of) the mouse or stylus buttons is double clicked. Implementors should call event->ignore() if they do not actually use the event. Default implementation ignores this event.

Parameters
eventstate and reason of this mouse or stylus press

Reimplemented from KoToolBase.

Reimplemented in ToolReferenceImages.

Definition at line 963 of file DefaultTool.cpp.

964{
966
968 if (shape && selection && !selection->isSelected(shape)) {
969
970 if (!(event->modifiers() & Qt::ShiftModifier)) {
971 selection->deselectAll();
972 }
973
974 selection->select(shape);
975 }
976
978}
void explicitUserStrokeEndRequest() override
explicitUserStrokeEndRequest is called by the input manager when the user presses Enter key or any eq...
Qt::KeyboardModifiers modifiers() const

References explicitUserStrokeEndRequest(), koSelection(), KoPointerEvent::modifiers(), KoPointerEvent::point, selection(), KoShapeManager::shapeAt(), shapeManager(), and KoFlake::ShapeOnTop.

◆ mouseMoveEvent()

void DefaultTool::mouseMoveEvent ( KoPointerEvent * event)
overridevirtual

Called when the mouse or stylus moved over the canvas. Implementors should call event->ignore() if they do not actually use the event.

Parameters
eventstate and reason of this mouse or stylus move

Implements KoToolBase.

Definition at line 910 of file DefaultTool.cpp.

911{
913 if (currentStrategy() == 0 && koSelection() && koSelection()->count() > 0) {
914 QRectF bound = handlesSize();
915
916 if (bound.contains(event->point)) {
917 bool inside;
918 KoFlake::SelectionHandle newDirection = handleAt(event->point, &inside);
919
920 if (inside != m_mouseWasInsideHandles || m_lastHandle != newDirection) {
921 m_lastHandle = newDirection;
923 }
924 } else {
927
928 // there used to be guides... :'''(
929 }
930 } else {
931 // there used to be guides... :'''(
932 }
933
934
935 updateCursor();
936}
void updateCursor()
void mouseMoveEvent(KoPointerEvent *event) override

References KoInteractionTool::currentStrategy(), handleAt(), handlesSize(), koSelection(), m_lastHandle, m_mouseWasInsideHandles, KoInteractionTool::mouseMoveEvent(), KoFlake::NoHandle, KoPointerEvent::point, and updateCursor().

◆ mousePressEvent()

void DefaultTool::mousePressEvent ( KoPointerEvent * event)
overridevirtual

Called when (one of) the mouse or stylus buttons is pressed. Implementors should call event->ignore() if they do not actually use the event.

Parameters
eventstate and reason of this mouse or stylus press

Implements KoToolBase.

Definition at line 895 of file DefaultTool.cpp.

896{
897 // this tool only works on a vector layer right now, so give a warning if another layer type is trying to use it
898 if (!isValidForCurrentLayer()) {
899 KisCanvas2 *kiscanvas = static_cast<KisCanvas2 *>(canvas());
900 kiscanvas->viewManager()->showFloatingMessage(
901 i18n("This tool only works on vector layers. You probably want the move tool."),
902 QIcon(), 2000, KisFloatingMessage::Medium, Qt::AlignCenter);
903 return;
904 }
905
907 updateCursor();
908}
virtual bool isValidForCurrentLayer() const
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
void mousePressEvent(KoPointerEvent *event) override

References KoToolBase::canvas(), isValidForCurrentLayer(), KisFloatingMessage::Medium, KoInteractionTool::mousePressEvent(), KisViewManager::showFloatingMessage(), updateCursor(), and KisCanvas2::viewManager().

◆ mouseReleaseEvent()

void DefaultTool::mouseReleaseEvent ( KoPointerEvent * event)
overridevirtual

Called when (one of) the mouse or stylus buttons is released. Implementors should call event->ignore() if they do not actually use the event.

Parameters
eventstate and reason of this mouse or stylus release

Implements KoToolBase.

Definition at line 957 of file DefaultTool.cpp.

958{
960 updateCursor();
961}
void mouseReleaseEvent(KoPointerEvent *event) override

References KoInteractionTool::mouseReleaseEvent(), and updateCursor().

◆ moveSelection()

bool DefaultTool::moveSelection ( int direction,
Qt::KeyboardModifiers modifiers )
private

Definition at line 980 of file DefaultTool.cpp.

981{
982 bool result = false;
983
984 qreal x = 0.0, y = 0.0;
985 if (direction == Qt::Key_Left) {
986 x = -5;
987 } else if (direction == Qt::Key_Right) {
988 x = 5;
989 } else if (direction == Qt::Key_Up) {
990 y = -5;
991 } else if (direction == Qt::Key_Down) {
992 y = 5;
993 }
994
995 if (x != 0.0 || y != 0.0) { // actually move
996
997 if ((modifiers & Qt::ShiftModifier) != 0) {
998 x *= 10;
999 y *= 10;
1000 } else if ((modifiers & Qt::AltModifier) != 0) { // more precise
1001 x /= 5;
1002 y /= 5;
1003 }
1004
1006
1007 if (!shapes.isEmpty()) {
1008 canvas()->addCommand(new KoShapeMoveCommand(shapes, QPointF(x, y)));
1009 result = true;
1010 }
1011 }
1012
1013 return result;
1014}
const QList< KoShape * > selectedEditableShapes() const
The undo / redo command for shape moving.

References KoCanvasBase::addCommand(), KoToolBase::canvas(), koSelection(), and KoSelection::selectedEditableShapes().

◆ paint()

void DefaultTool::paint ( QPainter & painter,
const KoViewConverter & converter )
overridevirtual

Called by the canvas to paint any decorations that the tool deems needed. The painter has the top left of the canvas as its origin.

Parameters
painterused for painting the shape
converterto convert between internal and view coordinates.

Selection masks don't render the outline of the shapes, so we should do that explicitly when rendering them via selection

Implements KoToolBase.

Definition at line 846 of file DefaultTool.cpp.

847{
849 if (selection) {
850 m_decorator.reset(new SelectionDecorator(canvas()->resourceManager()));
851
852 {
858 KisCanvas2 *kisCanvas = static_cast<KisCanvas2 *>(canvas());
859 KisNodeSP node = kisCanvas->viewManager()->nodeManager()->activeNode();
860 const bool isSelectionMask = node && node->inherits("KisSelectionMask");
861 m_decorator->setForceShapeOutlines(isSelectionMask);
862 }
863
864 m_decorator->setSelection(selection);
865 m_decorator->setHandleRadius(handleRadius());
866 m_decorator->setDecorationThickness(decorationThickness());
867 m_decorator->setShowFillGradientHandles(hasInteractionFactory(EditFillGradientFactoryId));
868 m_decorator->setShowStrokeFillGradientHandles(hasInteractionFactory(EditStrokeGradientFactoryId));
869 m_decorator->setShowFillMeshGradientHandles(hasInteractionFactory(EditFillMeshGradientFactoryId));
870 m_decorator->setCurrentMeshGradientHandles(m_selectedMeshHandle, m_hoveredMeshHandle);
871 m_decorator->paint(painter, converter);
872 }
873
874 KoInteractionTool::paint(painter, converter);
875
876 painter.save();
877 painter.setTransform(converter.documentToView(), true);
878 canvas()->snapGuide()->paint(painter, converter);
879 painter.restore();
880}
KoShapeMeshGradientHandles::Handle m_selectedMeshHandle
QScopedPointer< SelectionDecorator > m_decorator
KoShapeMeshGradientHandles::Handle m_hoveredMeshHandle
KisNodeSP activeNode()
Convenience function to get the active layer or mask.
KisNodeManager * nodeManager() const
The node manager handles everything about nodes.
bool hasInteractionFactory(const QString &id)
void paint(QPainter &painter, const KoViewConverter &converter) override
void paint(QPainter &painter, const KoViewConverter &converter)
paints the guide
int handleRadius() const
Convenience function to get the current handle radius.
int decorationThickness() const
decorationThickness The minimum thickness for tool decoration lines, this is derived from the screen ...
bool isSelectionMask(KisNodeSP node)

References KisNodeManager::activeNode(), KoToolBase::canvas(), KoToolBase::decorationThickness(), KoViewConverter::documentToView(), KoToolBase::handleRadius(), KoInteractionTool::hasInteractionFactory(), isSelectionMask(), koSelection(), m_decorator, m_hoveredMeshHandle, m_selectedMeshHandle, KisViewManager::nodeManager(), KoSnapGuide::paint(), KoInteractionTool::paint(), selection(), KoCanvasBase::snapGuide, and KisCanvas2::viewManager().

◆ paste()

bool DefaultTool::paste ( )
overridevirtual

reimplemented

Reimplemented from KoToolBase.

Definition at line 1079 of file DefaultTool.cpp.

1080{
1081 // we no longer have to do anything as tool Proxy will do it for us
1082 return false;
1083}

◆ popupActionsMenu()

QMenu * DefaultTool::popupActionsMenu ( )
overridevirtual
Returns
a menu with context-aware actions for the current selection. If the returned value is null, no context menu is shown.

Reimplemented from KoToolBase.

Reimplemented in ToolReferenceImages.

Definition at line 1914 of file DefaultTool.cpp.

1915{
1916 if (m_contextMenu) {
1917 m_contextMenu->clear();
1918
1919 m_contextMenu->addSection(i18n("Vector Shape Actions"));
1920 m_contextMenu->addSeparator();
1921
1922 QMenu *transform = m_contextMenu->addMenu(i18n("Transform"));
1923
1924 transform->addAction(action("object_transform_rotate_90_cw"));
1925 transform->addAction(action("object_transform_rotate_90_ccw"));
1926 transform->addAction(action("object_transform_rotate_180"));
1927 transform->addSeparator();
1928 transform->addAction(action("object_transform_mirror_horizontally"));
1929 transform->addAction(action("object_transform_mirror_vertically"));
1930 transform->addSeparator();
1931 transform->addAction(action("object_transform_reset"));
1932
1933 if (action("object_unite")->isEnabled() ||
1934 action("object_intersect")->isEnabled() ||
1935 action("object_subtract")->isEnabled() ||
1936 action("object_split")->isEnabled()) {
1937
1938 QMenu *transform = m_contextMenu->addMenu(i18n("Logical Operations"));
1939 transform->addAction(action("object_unite"));
1940 transform->addAction(action("object_intersect"));
1941 transform->addAction(action("object_subtract"));
1942 transform->addAction(action("object_split"));
1943 }
1944
1945 m_contextMenu->addSeparator();
1946
1947 m_contextMenu->addAction(action("edit_cut"));
1948 m_contextMenu->addAction(action("edit_copy"));
1949 m_contextMenu->addAction(action("edit_paste"));
1950 m_contextMenu->addAction(action("paste_at"));
1951
1952 m_contextMenu->addSeparator();
1953
1954 m_contextMenu->addAction(action("object_order_front"));
1955 m_contextMenu->addAction(action("object_order_raise"));
1956 m_contextMenu->addAction(action("object_order_lower"));
1957 m_contextMenu->addAction(action("object_order_back"));
1958
1959 if (action("object_group")->isEnabled() || action("object_ungroup")->isEnabled()) {
1960 m_contextMenu->addSeparator();
1961 m_contextMenu->addAction(action("object_group"));
1962 m_contextMenu->addAction(action("object_ungroup"));
1963 }
1964 m_contextMenu->addSeparator();
1965 m_contextMenu->addAction(action("convert_shapes_to_vector_selection"));
1966 }
1967
1968 return m_contextMenu.data();
1969}
QScopedPointer< QMenu > m_contextMenu

References KoToolBase::action(), and m_contextMenu.

◆ recalcSelectionBox()

void DefaultTool::recalcSelectionBox ( KoSelection * selection)
private

Definition at line 1166 of file DefaultTool.cpp.

1167{
1169
1170 QTransform matrix = selection->absoluteTransformation();
1171 m_selectionOutline = matrix.map(QPolygonF(selection->outlineRect()));
1172 m_angle = 0.0;
1173
1174 QPolygonF outline = m_selectionOutline; //shorter name in the following :)
1175 m_selectionBox[KoFlake::TopMiddleHandle] = (outline.value(0) + outline.value(1)) / 2;
1176 m_selectionBox[KoFlake::TopRightHandle] = outline.value(1);
1177 m_selectionBox[KoFlake::RightMiddleHandle] = (outline.value(1) + outline.value(2)) / 2;
1178 m_selectionBox[KoFlake::BottomRightHandle] = outline.value(2);
1179 m_selectionBox[KoFlake::BottomMiddleHandle] = (outline.value(2) + outline.value(3)) / 2;
1180 m_selectionBox[KoFlake::BottomLeftHandle] = outline.value(3);
1181 m_selectionBox[KoFlake::LeftMiddleHandle] = (outline.value(3) + outline.value(0)) / 2;
1182 m_selectionBox[KoFlake::TopLeftHandle] = outline.value(0);
1183 if (selection->count() == 1) {
1184#if 0 // TODO detect mirroring
1186
1187 if (s->scaleX() < 0) { // vertically mirrored: swap left / right
1191 }
1192 if (s->scaleY() < 0) { // vertically mirrored: swap top / bottom
1196 }
1197#endif
1198 }
1199}
KoShape * firstSelectedShape() const
#define KIS_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:75

References KoFlake::BottomLeftHandle, KoFlake::BottomMiddleHandle, KoFlake::BottomRightHandle, KoSelection::firstSelectedShape(), KIS_ASSERT_RECOVER_RETURN, koSelection(), KoFlake::LeftMiddleHandle, m_angle, m_selectionBox, m_selectionOutline, KoFlake::RightMiddleHandle, selection(), KoFlake::TopLeftHandle, KoFlake::TopMiddleHandle, and KoFlake::TopRightHandle.

◆ rotationOfHandle()

qreal DefaultTool::rotationOfHandle ( KoFlake::SelectionHandle handle,
bool useEdgeRotation )
private

Returns rotation angle of given handle of the current selection.

Definition at line 609 of file DefaultTool.cpp.

610{
611 QPointF selectionCenter = koSelection()->absolutePosition();
612 QPointF direction;
613
614 switch (handle) {
616 if (useEdgeRotation) {
619 } else {
620 QPointF handlePosition = koSelection()->absolutePosition(KoFlake::TopLeft);
621 handlePosition += 0.5 * (koSelection()->absolutePosition(KoFlake::TopRight) - handlePosition);
622 direction = handlePosition - selectionCenter;
623 }
624 break;
626 direction = (QVector2D(koSelection()->absolutePosition(KoFlake::TopRight) - koSelection()->absolutePosition(KoFlake::TopLeft)).normalized() + QVector2D(koSelection()->absolutePosition(KoFlake::TopRight) - koSelection()->absolutePosition(KoFlake::BottomRight)).normalized()).toPointF();
627 break;
629 if (useEdgeRotation) {
632 } else {
633 QPointF handlePosition = koSelection()->absolutePosition(KoFlake::TopRight);
634 handlePosition += 0.5 * (koSelection()->absolutePosition(KoFlake::BottomRight) - handlePosition);
635 direction = handlePosition - selectionCenter;
636 }
637 break;
639 direction = (QVector2D(koSelection()->absolutePosition(KoFlake::BottomRight) - koSelection()->absolutePosition(KoFlake::BottomLeft)).normalized() + QVector2D(koSelection()->absolutePosition(KoFlake::BottomRight) - koSelection()->absolutePosition(KoFlake::TopRight)).normalized()).toPointF();
640 break;
642 if (useEdgeRotation) {
645 } else {
646 QPointF handlePosition = koSelection()->absolutePosition(KoFlake::BottomLeft);
647 handlePosition += 0.5 * (koSelection()->absolutePosition(KoFlake::BottomRight) - handlePosition);
648 direction = handlePosition - selectionCenter;
649 }
650 break;
652 direction = koSelection()->absolutePosition(KoFlake::BottomLeft) - selectionCenter;
653 direction = (QVector2D(koSelection()->absolutePosition(KoFlake::BottomLeft) - koSelection()->absolutePosition(KoFlake::BottomRight)).normalized() + QVector2D(koSelection()->absolutePosition(KoFlake::BottomLeft) - koSelection()->absolutePosition(KoFlake::TopLeft)).normalized()).toPointF();
654 break;
656 if (useEdgeRotation) {
659 } else {
660 QPointF handlePosition = koSelection()->absolutePosition(KoFlake::TopLeft);
661 handlePosition += 0.5 * (koSelection()->absolutePosition(KoFlake::BottomLeft) - handlePosition);
662 direction = handlePosition - selectionCenter;
663 }
664 break;
666 direction = koSelection()->absolutePosition(KoFlake::TopLeft) - selectionCenter;
667 direction = (QVector2D(koSelection()->absolutePosition(KoFlake::TopLeft) - koSelection()->absolutePosition(KoFlake::TopRight)).normalized() + QVector2D(koSelection()->absolutePosition(KoFlake::TopLeft) - koSelection()->absolutePosition(KoFlake::BottomLeft)).normalized()).toPointF();
668 break;
670 return 0.0;
671 break;
672 }
673
674 qreal rotation = atan2(direction.y(), direction.x()) * 180.0 / M_PI;
675
676 switch (handle) {
678 if (useEdgeRotation) {
679 rotation -= 0.0;
680 } else {
681 rotation -= 270.0;
682 }
683 break;
685 rotation -= 315.0;
686 break;
688 if (useEdgeRotation) {
689 rotation -= 90.0;
690 } else {
691 rotation -= 0.0;
692 }
693 break;
695 rotation -= 45.0;
696 break;
698 if (useEdgeRotation) {
699 rotation -= 180.0;
700 } else {
701 rotation -= 90.0;
702 }
703 break;
705 rotation -= 135.0;
706 break;
708 if (useEdgeRotation) {
709 rotation -= 270.0;
710 } else {
711 rotation -= 180.0;
712 }
713 break;
715 rotation -= 225.0;
716 break;
717 default:
718 ;
719 }
720
721 if (rotation < 0.0) {
722 rotation += 360.0;
723 }
724
725 return rotation;
726}
QPointF absolutePosition(KoFlake::AnchorPosition anchor=KoFlake::Center) const
Definition KoShape.cpp:653
#define M_PI
Definition kis_global.h:111
KRITAIMAGE_EXPORT qreal atan2(qreal y, qreal x)
atan2 replacement

References KoShape::absolutePosition(), KoFlake::BottomLeft, KoFlake::BottomLeftHandle, KoFlake::BottomMiddleHandle, KoFlake::BottomRight, KoFlake::BottomRightHandle, koSelection(), KoFlake::LeftMiddleHandle, M_PI, KoFlake::NoHandle, KoFlake::RightMiddleHandle, KoFlake::TopLeft, KoFlake::TopLeftHandle, KoFlake::TopMiddleHandle, KoFlake::TopRight, and KoFlake::TopRightHandle.

◆ selectAll()

bool DefaultTool::selectAll ( )
overridevirtual

reimplemented

Reimplemented from KoToolBase.

Definition at line 1085 of file DefaultTool.cpp.

1086{
1087 Q_ASSERT(canvas());
1088 Q_ASSERT(canvas()->selectedShapesProxy());
1089 Q_FOREACH(KoShape *shape, canvas()->shapeManager()->shapes()) {
1090 if (!shape->isSelectable()) continue;
1092 }
1094
1095 return true;
1096}
void select(KoShape *shape)
bool isSelectable() const
Definition KoShape.cpp:1014

References KoToolBase::canvas(), KoShape::isSelectable(), KoToolBase::repaintDecorations(), KoSelection::select(), KoCanvasBase::selectedShapesProxy(), KoSelectedShapesProxy::selection(), and shapeManager().

◆ selection()

KoToolSelection * DefaultTool::selection ( )
overridevirtual

reimplemented

Reimplemented from KoToolBase.

Definition at line 1909 of file DefaultTool.cpp.

1910{
1911 return m_selectionHandler;
1912}

References m_selectionHandler.

◆ selectionAlign

void DefaultTool::selectionAlign ( int _align)
privateslot

Definition at line 1555 of file DefaultTool.cpp.

1556{
1558 static_cast<KoShapeAlignCommand::Align>(_align);
1559
1561 if (!selection) return;
1562
1563 QList<KoShape *> editableShapes = selection->selectedEditableShapes();
1564 if (editableShapes.isEmpty()) {
1565 return;
1566 }
1567
1568 // TODO add an option to the widget so that one can align to the page
1569 // with multiple selected shapes too
1570
1571 QRectF bb;
1572
1573 // single selected shape is automatically aligned to document rect
1574 if (editableShapes.count() == 1) {
1575 if (!canvas()->resourceManager()->hasResource(KoCanvasResource::PageSize)) {
1576 return;
1577 }
1578 bb = QRectF(QPointF(0, 0), canvas()->resourceManager()->sizeResource(KoCanvasResource::PageSize));
1579 } else {
1580 bb = KoShape::absoluteOutlineRect(editableShapes);
1581 }
1582
1583 KoShapeAlignCommand *cmd = new KoShapeAlignCommand(editableShapes, align, bb);
1584 canvas()->addCommand(cmd);
1585}
The undo / redo command for aligning shapes.
Align
The different alignment options for this command.
QRectF absoluteOutlineRect() const
Definition KoShape.cpp:368
@ PageSize
The size of the (current) page in postscript points.

References KoShape::absoluteOutlineRect(), KoCanvasBase::addCommand(), KoToolBase::canvas(), koSelection(), KoCanvasResource::PageSize, and selection().

◆ selectionBooleanOp

void DefaultTool::selectionBooleanOp ( int booleanOp)
privateslot

Definition at line 1427 of file DefaultTool.cpp.

1428{
1430 if (!selection) return;
1431
1432 QList<KoShape *> editableShapes = selection->selectedEditableShapes();
1433 if (editableShapes.isEmpty()) {
1434 return;
1435 }
1436
1437 QVector<QPainterPath> srcOutlines;
1438 QPainterPath dstOutline;
1439 KUndo2MagicString actionName = kundo2_noi18n("BUG: boolean action name");
1440
1441 // TODO: implement a reference shape selection dialog!
1442 const int referenceShapeIndex = 0;
1443 KoShape *referenceShape = editableShapes[referenceShapeIndex];
1444
1445 KisCanvas2 *kisCanvas = static_cast<KisCanvas2 *>(canvas());
1447 const QTransform booleanWorkaroundTransform =
1449
1450 Q_FOREACH (KoShape *shape, editableShapes) {
1451 srcOutlines <<
1452 booleanWorkaroundTransform.map(
1453 shape->absoluteTransformation().map(
1454 shape->outline()));
1455 }
1456
1457 if (booleanOp == BooleanUnion) {
1458 Q_FOREACH (const QPainterPath &path, srcOutlines) {
1459 dstOutline |= path;
1460 }
1461 actionName = kundo2_i18n("Unite Shapes");
1462 } else if (booleanOp == BooleanIntersection) {
1463 for (int i = 0; i < srcOutlines.size(); i++) {
1464 if (i == 0) {
1465 dstOutline = srcOutlines[i];
1466 } else {
1467 dstOutline &= srcOutlines[i];
1468 }
1469 }
1470
1471 // there is a bug in Qt, sometimes it leaves the resulting
1472 // outline open, so just close it explicitly.
1473 dstOutline.closeSubpath();
1474
1475 actionName = kundo2_i18n("Intersect Shapes");
1476
1477 } else if (booleanOp == BooleanSubtraction) {
1478 for (int i = 0; i < srcOutlines.size(); i++) {
1479 dstOutline = srcOutlines[referenceShapeIndex];
1480 if (i != referenceShapeIndex) {
1481 dstOutline -= srcOutlines[i];
1482 }
1483 }
1484
1485 actionName = kundo2_i18n("Subtract Shapes");
1486 }
1487
1488 dstOutline = booleanWorkaroundTransform.inverted().map(dstOutline);
1489
1490 KoShape *newShape = 0;
1491
1492 if (!dstOutline.isEmpty()) {
1493 newShape = KoPathShape::createShapeFromPainterPath(dstOutline);
1494 }
1495
1496 KUndo2Command *cmd = new KUndo2Command(actionName);
1497
1498 new KoKeepShapesSelectedCommand(editableShapes, {}, canvas()->selectedShapesProxy(), false, cmd);
1499
1500 QList<KoShape*> newSelectedShapes;
1501
1502 if (newShape) {
1503 newShape->setBackground(referenceShape->background());
1504 newShape->setStroke(referenceShape->stroke());
1505 newShape->setZIndex(referenceShape->zIndex());
1506
1507 KoShapeContainer *parent = referenceShape->parent();
1508 canvas()->shapeController()->addShapeDirect(newShape, parent, cmd);
1509
1510 newSelectedShapes << newShape;
1511 }
1512
1513 canvas()->shapeController()->removeShapes(editableShapes, cmd);
1514
1515 new KoKeepShapesSelectedCommand({}, newSelectedShapes, canvas()->selectedShapesProxy(), true, cmd);
1516
1517 canvas()->addCommand(cmd);
1518}
KisImageWSP image() const
QPointer< KoShapeController > shapeController
static KoPathShape * createShapeFromPainterPath(const QPainterPath &path)
Creates path shape from given QPainterPath.
void setZIndex(qint16 zIndex)
Definition KoShape.cpp:954
virtual QPainterPath outline() const
Definition KoShape.cpp:630
virtual KoShapeStrokeModelSP stroke() const
Definition KoShape.cpp:1067
KoShapeContainer * parent() const
Definition KoShape.cpp:1039
virtual void setStroke(KoShapeStrokeModelSP stroke)
Definition KoShape.cpp:1081
QTransform absoluteTransformation() const
Definition KoShape.cpp:382
virtual void setBackground(QSharedPointer< KoShapeBackground > background)
Definition KoShape.cpp:918
virtual QSharedPointer< KoShapeBackground > background() const
Definition KoShape.cpp:926
qint16 zIndex() const
Definition KoShape.cpp:600
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:128
KUndo2MagicString kundo2_i18n(const char *text)
KUndo2MagicString kundo2_noi18n(const QString &text)
ChildIterator< value_type, is_const > parent(const ChildIterator< value_type, is_const > &it)
Definition KisForest.h:327
QTransform pathShapeBooleanSpaceWorkaround(KisImageSP image)

References KoShape::absoluteTransformation(), KoCanvasBase::addCommand(), KoShape::background(), KoToolBase::canvas(), KoPathShape::createShapeFromPainterPath(), KisCanvas2::image(), KIS_SAFE_ASSERT_RECOVER_RETURN, koSelection(), kundo2_i18n(), kundo2_noi18n(), KoShape::outline(), KoShape::parent(), KritaUtils::pathShapeBooleanSpaceWorkaround(), KoCanvasBase::selectedShapesProxy(), selection(), KoShape::setBackground(), KoShape::setStroke(), KoShape::setZIndex(), KoCanvasBase::shapeController, KoShape::stroke(), and KoShape::zIndex().

◆ selectionBringToFront

void DefaultTool::selectionBringToFront ( )
privateslot

Definition at line 1605 of file DefaultTool.cpp.

1606{
1608}
void selectionReorder(KoShapeReorderCommand::MoveShapeType order)
@ BringToFront
Raise the selected shape to be on top of all shapes.

References KoShapeReorderCommand::BringToFront, and selectionReorder().

◆ selectionDistribute

void DefaultTool::selectionDistribute ( int _distribute)
privateslot

Definition at line 1587 of file DefaultTool.cpp.

1588{
1590 static_cast<KoShapeDistributeCommand::Distribute>(_distribute);
1591
1593 if (!selection) return;
1594
1595 QList<KoShape *> editableShapes = selection->selectedEditableShapes();
1596 if (editableShapes.size() < 3) {
1597 return;
1598 }
1599
1600 QRectF bb = KoShape::absoluteOutlineRect(editableShapes);
1601 KoShapeDistributeCommand *cmd = new KoShapeDistributeCommand(editableShapes, distribute, bb);
1602 canvas()->addCommand(cmd);
1603}
The undo / redo command for distributing shapes.
Distribute
The different options to distribute with this command.

References KoShape::absoluteOutlineRect(), KoCanvasBase::addCommand(), KoToolBase::canvas(), koSelection(), and selection().

◆ selectionGroup

void DefaultTool::selectionGroup ( )
privateslot

Definition at line 1291 of file DefaultTool.cpp.

1292{
1294 if (!selection) return;
1295
1296 QList<KoShape *> selectedShapes = selection->selectedEditableShapes();
1297 std::sort(selectedShapes.begin(), selectedShapes.end(), KoShape::compareShapeZIndex);
1298 if (selectedShapes.isEmpty()) return;
1299
1300 const int groupZIndex = selectedShapes.last()->zIndex();
1301
1302 KoShapeGroup *group = new KoShapeGroup();
1303 group->setZIndex(groupZIndex);
1304 // TODO what if only one shape is left?
1305 KUndo2Command *cmd = new KUndo2Command(kundo2_i18n("Group shapes"));
1306 new KoKeepShapesSelectedCommand(selectedShapes, {}, canvas()->selectedShapesProxy(), false, cmd);
1307 canvas()->shapeController()->addShapeDirect(group, 0, cmd);
1308 new KoShapeGroupCommand(group, selectedShapes, true, cmd);
1309 new KoKeepShapesSelectedCommand({}, {group}, canvas()->selectedShapesProxy(), true, cmd);
1310 canvas()->addCommand(cmd);
1311
1312 // update selection so we can ungroup immediately again
1313 selection->deselectAll();
1314 selection->select(group);
1315}
The undo / redo command for grouping shapes.
static bool compareShapeZIndex(KoShape *s1, KoShape *s2)
Definition KoShape.cpp:434

References KoCanvasBase::addCommand(), KoToolBase::canvas(), KoShape::compareShapeZIndex(), koSelection(), kundo2_i18n(), KoCanvasBase::selectedShapesProxy(), selection(), KoShape::setZIndex(), and KoCanvasBase::shapeController.

◆ selectionMoveDown

void DefaultTool::selectionMoveDown ( )
privateslot

Definition at line 1615 of file DefaultTool.cpp.

1616{
1618}
@ LowerShape
Lower the selected shape to the level that it is below the shape that is below it.

References KoShapeReorderCommand::LowerShape, and selectionReorder().

◆ selectionMoveUp

void DefaultTool::selectionMoveUp ( )
privateslot

Definition at line 1610 of file DefaultTool.cpp.

1611{
1613}
@ RaiseShape
raise the selected shape to the level that it is above the shape that is on top of it.

References KoShapeReorderCommand::RaiseShape, and selectionReorder().

◆ selectionReorder()

void DefaultTool::selectionReorder ( KoShapeReorderCommand::MoveShapeType order)
private

Definition at line 1625 of file DefaultTool.cpp.

1626{
1628 if (!selection) {
1629 return;
1630 }
1631
1632 QList<KoShape *> selectedShapes = selection->selectedEditableShapes();
1633 if (selectedShapes.isEmpty()) {
1634 return;
1635 }
1636
1637 KUndo2Command *cmd = KoShapeReorderCommand::createCommand(selectedShapes, shapeManager(), order);
1638 if (cmd) {
1639 canvas()->addCommand(cmd);
1640 }
1641}
static KoShapeReorderCommand * createCommand(const QList< KoShape * > &shapes, KoShapeManager *manager, MoveShapeType move, KUndo2Command *parent=0)

References KoCanvasBase::addCommand(), KoToolBase::canvas(), KoShapeReorderCommand::createCommand(), koSelection(), selection(), and shapeManager().

◆ selectionSendToBack

void DefaultTool::selectionSendToBack ( )
privateslot

Definition at line 1620 of file DefaultTool.cpp.

1621{
1623}
@ SendToBack
Lower the selected shape to be below all other shapes.

References selectionReorder(), and KoShapeReorderCommand::SendToBack.

◆ selectionSplitShapes

void DefaultTool::selectionSplitShapes ( )
privateslot

Definition at line 1520 of file DefaultTool.cpp.

1521{
1523 if (!selection) return;
1524
1525 QList<KoShape *> editableShapes = selection->selectedEditableShapes();
1526 if (editableShapes.isEmpty()) {
1527 return;
1528 }
1529
1530 KUndo2Command *cmd = new KUndo2Command(kundo2_i18n("Split Shapes"));
1531
1532 new KoKeepShapesSelectedCommand(editableShapes, {}, canvas()->selectedShapesProxy(), false, cmd);
1533 QList<KoShape*> newShapes;
1534
1535 Q_FOREACH (KoShape *shape, editableShapes) {
1536 KoPathShape *pathShape = dynamic_cast<KoPathShape*>(shape);
1537 if (!pathShape) return;
1538
1539 QList<KoPathShape*> splitShapes;
1540 if (pathShape->separate(splitShapes)) {
1541 QList<KoShape*> normalShapes = implicitCastList<KoShape*>(splitShapes);
1542
1543 KoShapeContainer *parent = shape->parent();
1544 canvas()->shapeController()->addShapesDirect(normalShapes, parent, cmd);
1545 canvas()->shapeController()->removeShape(shape, cmd);
1546 newShapes << normalShapes;
1547 }
1548 }
1549
1550 new KoKeepShapesSelectedCommand({}, newShapes, canvas()->selectedShapesProxy(), true, cmd);
1551
1552 canvas()->addCommand(cmd);
1553}
The position of a path point within a path shape.
Definition KoPathShape.h:63
bool separate(QList< KoPathShape * > &separatedPaths)
Creates separate path shapes, one for each existing subpath.

References KoCanvasBase::addCommand(), KoToolBase::canvas(), koSelection(), kundo2_i18n(), KoShape::parent(), KoCanvasBase::selectedShapesProxy(), selection(), KoPathShape::separate(), and KoCanvasBase::shapeController.

◆ selectionTransform

void DefaultTool::selectionTransform ( int transformAction)
privateslot

Definition at line 1349 of file DefaultTool.cpp.

1350{
1352 if (!selection) return;
1353
1354 QList<KoShape *> editableShapes = selection->selectedEditableShapes();
1355 if (editableShapes.isEmpty()) {
1356 return;
1357 }
1358
1359 QTransform applyTransform;
1360 bool shouldReset = false;
1361 KUndo2MagicString actionName = kundo2_noi18n("BUG: No transform action");
1362
1363
1364 switch (TransformActionType(transformAction)) {
1365 case TransformRotate90CW:
1366 applyTransform.rotate(90.0);
1367 actionName = kundo2_i18n("Rotate Object 90° CW");
1368 break;
1369 case TransformRotate90CCW:
1370 applyTransform.rotate(-90.0);
1371 actionName = kundo2_i18n("Rotate Object 90° CCW");
1372 break;
1373 case TransformRotate180:
1374 applyTransform.rotate(180.0);
1375 actionName = kundo2_i18n("Rotate Object 180°");
1376 break;
1377 case TransformMirrorX:
1378 applyTransform.scale(-1.0, 1.0);
1379 actionName = kundo2_i18n("Mirror Object Horizontally");
1380 break;
1381 case TransformMirrorY:
1382 applyTransform.scale(1.0, -1.0);
1383 actionName = kundo2_i18n("Mirror Object Vertically");
1384 break;
1385 case TransformReset:
1386 shouldReset = true;
1387 actionName = kundo2_i18n("Reset Object Transformations");
1388 break;
1389 }
1390
1391 if (!shouldReset && applyTransform.isIdentity()) return;
1392
1393 QList<QTransform> oldTransforms;
1394 QList<QTransform> newTransforms;
1395
1396 const QRectF outlineRect = KoShape::absoluteOutlineRect(editableShapes);
1397 const QPointF centerPoint = outlineRect.center();
1398 const QTransform centerTrans = QTransform::fromTranslate(centerPoint.x(), centerPoint.y());
1399 const QTransform centerTransInv = QTransform::fromTranslate(-centerPoint.x(), -centerPoint.y());
1400
1401 // we also add selection to the list of transformed shapes, so that its outline is updated correctly
1402 QList<KoShape*> transformedShapes = editableShapes;
1403 transformedShapes << selection;
1404
1405 Q_FOREACH (KoShape *shape, transformedShapes) {
1406 oldTransforms.append(shape->transformation());
1407
1408 QTransform t;
1409
1410 if (!shouldReset) {
1411 const QTransform world = shape->absoluteTransformation();
1412 t = world * centerTransInv * applyTransform * centerTrans * world.inverted() * shape->transformation();
1413 } else {
1414 const QPointF center = shape->outlineRect().center();
1415 const QPointF offset = shape->transformation().map(center) - center;
1416 t = QTransform::fromTranslate(offset.x(), offset.y());
1417 }
1418
1419 newTransforms.append(t);
1420 }
1421
1422 KoShapeTransformCommand *cmd = new KoShapeTransformCommand(transformedShapes, oldTransforms, newTransforms);
1423 cmd->setText(actionName);
1424 canvas()->addCommand(cmd);
1425}
void setText(const KUndo2MagicString &text)
virtual QRectF outlineRect() const
Definition KoShape.cpp:637
QTransform transformation() const
Returns the shapes local transformation matrix.
Definition KoShape.cpp:424

References KoShape::absoluteOutlineRect(), KoShape::absoluteTransformation(), KoCanvasBase::addCommand(), KoToolBase::canvas(), koSelection(), kundo2_i18n(), kundo2_noi18n(), KoShape::outlineRect(), selection(), KUndo2Command::setText(), and KoShape::transformation().

◆ selectionUngroup

void DefaultTool::selectionUngroup ( )
privateslot

Definition at line 1317 of file DefaultTool.cpp.

1318{
1320 if (!selection) return;
1321
1322 QList<KoShape *> selectedShapes = selection->selectedEditableShapes();
1323 std::sort(selectedShapes.begin(), selectedShapes.end(), KoShape::compareShapeZIndex);
1324
1325 KUndo2Command *cmd = 0;
1326 QList<KoShape*> newShapes;
1327
1328 // add a ungroup command for each found shape container to the macro command
1329 Q_FOREACH (KoShape *shape, selectedShapes) {
1330 KoShapeGroup *group = dynamic_cast<KoShapeGroup *>(shape);
1331 if (group) {
1332 if (!cmd) {
1333 cmd = new KUndo2Command(kundo2_i18n("Ungroup shapes"));
1334 new KoKeepShapesSelectedCommand(selectedShapes, {}, canvas()->selectedShapesProxy(), false, cmd);
1335 }
1336 newShapes << group->shapes();
1337 new KoShapeUngroupCommand(group, group->shapes(),
1338 group->parent() ? QList<KoShape *>() : shapeManager()->topLevelShapes(),
1339 cmd);
1340 canvas()->shapeController()->removeShape(group, cmd);
1341 }
1342 }
1343 if (cmd) {
1344 new KoKeepShapesSelectedCommand({}, newShapes, canvas()->selectedShapesProxy(), true, cmd);
1345 canvas()->addCommand(cmd);
1346 }
1347}
QList< KoShape * > shapes() const
The undo / redo command for ungrouping shapes.

References KoCanvasBase::addCommand(), KoToolBase::canvas(), KoShape::compareShapeZIndex(), koSelection(), kundo2_i18n(), KoShape::parent(), KoCanvasBase::selectedShapesProxy(), selection(), KoCanvasBase::shapeController, shapeManager(), KoShapeContainer::shapes(), and KoShapeManager::topLevelShapes().

◆ setupActions()

void DefaultTool::setupActions ( )
private

Definition at line 563 of file DefaultTool.cpp.

564{
566
573
575
580
585
587
588 addMappedAction(m_transformSignalsMapper, "object_transform_rotate_90_cw", TransformRotate90CW);
589 addMappedAction(m_transformSignalsMapper, "object_transform_rotate_90_ccw", TransformRotate90CCW);
590 addMappedAction(m_transformSignalsMapper, "object_transform_rotate_180", TransformRotate180);
591 addMappedAction(m_transformSignalsMapper, "object_transform_mirror_horizontally", TransformMirrorX);
592 addMappedAction(m_transformSignalsMapper, "object_transform_mirror_vertically", TransformMirrorY);
593 addMappedAction(m_transformSignalsMapper, "object_transform_reset", TransformReset);
594
596
597 addMappedAction(m_booleanSignalsMapper, "object_unite", BooleanUnion);
598 addMappedAction(m_booleanSignalsMapper, "object_intersect", BooleanIntersection);
599 addMappedAction(m_booleanSignalsMapper, "object_subtract", BooleanSubtraction);
600
605
606 m_contextMenu.reset(new QMenu());
607}
void addMappedAction(KisSignalMapper *mapper, const QString &actionId, int type)
The KisSignalMapper class bundles signals from identifiable senders.
@ VerticalCenterAlignment
Align centered vertically.
@ HorizontalLeftAlignment
Align left.
@ HorizontalCenterAlignment
Align Centered horizontally.
@ VerticalBottomAlignment
Align bottom.
@ HorizontalRightAlignment
Align Right.
@ HorizontalRightDistribution
Horizontal Right.
@ VerticalCenterDistribution
Vertical centered.
@ HorizontalGapsDistribution
Horizontal Gaps.
@ VerticalBottomDistribution
Vertical bottom.
@ HorizontalCenterDistribution
Horizontal centered.
@ HorizontalLeftDistribution
Horizontal Left.
@ PreformattedText
Text-on-Path falls under this or PrePositionedText depending on collapse of lines.
@ InlineWrap
Uses inline size to wrap and preserves spaces.

References addMappedAction(), KoShapeAlignCommand::HorizontalCenterAlignment, KoShapeDistributeCommand::HorizontalCenterDistribution, KoShapeDistributeCommand::HorizontalGapsDistribution, KoShapeAlignCommand::HorizontalLeftAlignment, KoShapeDistributeCommand::HorizontalLeftDistribution, KoShapeAlignCommand::HorizontalRightAlignment, KoShapeDistributeCommand::HorizontalRightDistribution, KoSvgTextShape::InlineWrap, m_alignSignalsMapper, m_booleanSignalsMapper, m_contextMenu, m_distributeSignalsMapper, m_textTypeSignalsMapper, m_transformSignalsMapper, KoSvgTextShape::PreformattedText, KoSvgTextShape::PrePositionedText, KoShapeAlignCommand::VerticalBottomAlignment, KoShapeDistributeCommand::VerticalBottomDistribution, KoShapeAlignCommand::VerticalCenterAlignment, KoShapeDistributeCommand::VerticalCenterDistribution, KoShapeDistributeCommand::VerticalGapsDistribution, KoShapeAlignCommand::VerticalTopAlignment, and KoShapeDistributeCommand::VerticalTopDistribution.

◆ shapeManager()

KoShapeManager * DefaultTool::shapeManager ( ) const
protectedvirtual

Reimplemented in ToolReferenceImages.

Definition at line 891 of file DefaultTool.cpp.

891 {
892 return canvas()->shapeManager();
893}
virtual KoShapeManager * shapeManager() const =0

References KoToolBase::canvas(), and KoCanvasBase::shapeManager().

◆ slotActivateEditFillGradient

void DefaultTool::slotActivateEditFillGradient ( bool value)
privateslot

Definition at line 480 of file DefaultTool.cpp.

481{
482 if (value) {
484 new MoveGradientHandleInteractionFactory(KoFlake::Fill,
485 1, EditFillGradientFactoryId, this));
486 } else {
487 removeInteractionFactory(EditFillGradientFactoryId);
488 }
490}
float value(const T *src, size_t ch)
void removeInteractionFactory(const QString &id)
void addInteractionFactory(KoInteractionStrategyFactory *factory)
@ Fill
Definition KoFlake.h:29

References KoInteractionTool::addInteractionFactory(), KoFlake::Fill, KoInteractionTool::removeInteractionFactory(), KoToolBase::repaintDecorations(), and value().

◆ slotActivateEditFillMeshGradient

void DefaultTool::slotActivateEditFillMeshGradient ( bool value)
privateslot

Definition at line 504 of file DefaultTool.cpp.

505{
506 if (value) {
508 m_tabbedOptionWidget, SLOT(slotMeshGradientHandleSelected(KoShapeMeshGradientHandles::Handle)));
510 new MoveMeshGradientHandleInteractionFactory(KoFlake::Fill, 1,
511 EditFillMeshGradientFactoryId, this));
512 } else {
514 m_tabbedOptionWidget, SLOT(slotMeshGradientHandleSelected(KoShapeMeshGradientHandles::Handle)));
515 removeInteractionFactory(EditFillMeshGradientFactoryId);
516 }
517}
void meshgradientHandleSelected(KoShapeMeshGradientHandles::Handle)

References KoInteractionTool::addInteractionFactory(), connect(), KoFlake::Fill, m_tabbedOptionWidget, meshgradientHandleSelected(), KoInteractionTool::removeInteractionFactory(), and value().

◆ slotActivateEditStrokeGradient

void DefaultTool::slotActivateEditStrokeGradient ( bool value)
privateslot

Definition at line 492 of file DefaultTool.cpp.

493{
494 if (value) {
496 new MoveGradientHandleInteractionFactory(KoFlake::StrokeFill,
497 0, EditStrokeGradientFactoryId, this));
498 } else {
499 removeInteractionFactory(EditStrokeGradientFactoryId);
500 }
502}
@ StrokeFill
Definition KoFlake.h:30

References KoInteractionTool::addInteractionFactory(), KoInteractionTool::removeInteractionFactory(), KoToolBase::repaintDecorations(), KoFlake::StrokeFill, and value().

◆ slotChangeTextType

void DefaultTool::slotChangeTextType ( int index)
privateslot

Definition at line 524 of file DefaultTool.cpp.

525{
527
528 if (shapes.isEmpty()) return;
529
531 KUndo2Command *parentCommand = new KUndo2Command();
532 bool convertableShape = false;
534 Q_FOREACH(KoShape *shape, shapes) {
535 KoSvgTextShape *textShape = dynamic_cast<KoSvgTextShape*>(shape);
536 if (textShape && textShape->textType() != type) {
537 KoSvgConvertTextTypeCommand *cmd = new KoSvgConvertTextTypeCommand(textShape, type, 0, parentCommand);
538 if (!convertableShape) {
539 convertableShape = true;
540 parentCommand->setText(cmd->text());
541 }
542 }
543 }
544
546 if (convertableShape) {
547 canvas()->addCommand(parentCommand);
548 }
549}
KUndo2MagicString text() const
The SvgConvertTextTypeCommand class This command allows textshapes to be converted between preformatt...
TextType textType() const
textType This enum gives an indication of what kind of text this shape is. The different text types a...

References KoCanvasBase::addCommand(), KoToolBase::canvas(), KisCommandUtils::FlipFlopCommand::FINALIZING, KisCommandUtils::FlipFlopCommand::INITIALIZING, koSelection(), KoSelection::selectedShapes(), KoCanvasBase::selectedShapesProxy(), KUndo2Command::setText(), KUndo2Command::text(), and KoSvgTextShape::textType().

◆ slotResetMeshGradientState

void DefaultTool::slotResetMeshGradientState ( )
privateslot

Definition at line 519 of file DefaultTool.cpp.

References m_selectedMeshHandle.

◆ updateActions

void DefaultTool::updateActions ( )
protectedslot

Update actions on selection change.

Definition at line 1804 of file DefaultTool.cpp.

1805{
1806 QList<KoShape*> editableShapes;
1807
1808 if (koSelection()) {
1809 editableShapes = koSelection()->selectedEditableShapes();
1810 }
1811
1812 const bool hasEditableShapes = !editableShapes.isEmpty();
1813
1814 action("object_order_front")->setEnabled(hasEditableShapes);
1815 action("object_order_raise")->setEnabled(hasEditableShapes);
1816 action("object_order_lower")->setEnabled(hasEditableShapes);
1817 action("object_order_back")->setEnabled(hasEditableShapes);
1818
1819 action("object_transform_rotate_90_cw")->setEnabled(hasEditableShapes);
1820 action("object_transform_rotate_90_ccw")->setEnabled(hasEditableShapes);
1821 action("object_transform_rotate_180")->setEnabled(hasEditableShapes);
1822 action("object_transform_mirror_horizontally")->setEnabled(hasEditableShapes);
1823 action("object_transform_mirror_vertically")->setEnabled(hasEditableShapes);
1824 action("object_transform_reset")->setEnabled(hasEditableShapes);
1825
1826 const bool multipleSelected = editableShapes.size() > 1;
1827
1828 const bool alignmentEnabled =
1829 multipleSelected ||
1830 (!editableShapes.isEmpty() &&
1832
1833 action("object_align_horizontal_left")->setEnabled(alignmentEnabled);
1834 action("object_align_horizontal_center")->setEnabled(alignmentEnabled);
1835 action("object_align_horizontal_right")->setEnabled(alignmentEnabled);
1836 action("object_align_vertical_top")->setEnabled(alignmentEnabled);
1837 action("object_align_vertical_center")->setEnabled(alignmentEnabled);
1838 action("object_align_vertical_bottom")->setEnabled(alignmentEnabled);
1839
1840 const bool distributionEnabled = editableShapes.size() > 2;
1841
1842 action("object_distribute_horizontal_left")->setEnabled(distributionEnabled);
1843 action("object_distribute_horizontal_center")->setEnabled(distributionEnabled);
1844 action("object_distribute_horizontal_right")->setEnabled(distributionEnabled);
1845 action("object_distribute_horizontal_gaps")->setEnabled(distributionEnabled);
1846
1847 action("object_distribute_vertical_top")->setEnabled(distributionEnabled);
1848 action("object_distribute_vertical_center")->setEnabled(distributionEnabled);
1849 action("object_distribute_vertical_bottom")->setEnabled(distributionEnabled);
1850 action("object_distribute_vertical_gaps")->setEnabled(distributionEnabled);
1851
1852 updateDistinctiveActions(editableShapes);
1853
1854 Q_EMIT selectionChanged(editableShapes.size());
1855}
virtual void updateDistinctiveActions(const QList< KoShape * > &editableShapes)

References KoToolBase::action(), KoToolBase::canvas(), koSelection(), KoCanvasResource::PageSize, KoCanvasBase::resourceManager, KoSelection::selectedEditableShapes(), KoToolBase::selectionChanged(), and updateDistinctiveActions().

◆ updateCursor()

void DefaultTool::updateCursor ( )
private

Definition at line 728 of file DefaultTool.cpp.

729{
730 if (tryUseCustomCursor()) return;
731
732 QCursor cursor = Qt::ArrowCursor;
733
734 QString statusText;
735
737 if (selection && selection->count() > 0) { // has a selection
738 bool editable = !selection->selectedEditableShapes().isEmpty();
739
742 int rotOctant = 8 + int(8.5 + m_angle / 45);
743
744 bool rotateHandle = false;
745 bool shearHandle = false;
746 switch (m_lastHandle) {
748 cursor = m_shearCursors[(0 + rotOctant) % 8];
749 shearHandle = true;
750 break;
752 cursor = m_rotateCursors[(1 + rotOctant) % 8];
753 rotateHandle = true;
754 break;
756 cursor = m_shearCursors[(2 + rotOctant) % 8];
757 shearHandle = true;
758 break;
760 cursor = m_rotateCursors[(3 + rotOctant) % 8];
761 rotateHandle = true;
762 break;
764 cursor = m_shearCursors[(4 + rotOctant) % 8];
765 shearHandle = true;
766 break;
768 cursor = m_rotateCursors[(5 + rotOctant) % 8];
769 rotateHandle = true;
770 break;
772 cursor = m_shearCursors[(6 + rotOctant) % 8];
773 shearHandle = true;
774 break;
776 cursor = m_rotateCursors[(7 + rotOctant) % 8];
777 rotateHandle = true;
778 break;
780 cursor = Qt::ArrowCursor;
781 break;
782 }
783 if (rotateHandle) {
784 statusText = i18n("Left click rotates around center, right click around highlighted position.");
785 }
786 if (shearHandle) {
787 statusText = i18n("Click and drag to shear selection.");
788 }
789
790
791 } else {
792 statusText = i18n("Click and drag to resize selection.");
794 int rotOctant = 8 + int(8.5 + m_angle / 45);
795 bool cornerHandle = false;
796 switch (m_lastHandle) {
798 cursor = m_sizeCursors[(0 + rotOctant) % 8];
799 break;
801 cursor = m_sizeCursors[(1 + rotOctant) % 8];
802 cornerHandle = true;
803 break;
805 cursor = m_sizeCursors[(2 + rotOctant) % 8];
806 break;
808 cursor = m_sizeCursors[(3 + rotOctant) % 8];
809 cornerHandle = true;
810 break;
812 cursor = m_sizeCursors[(4 + rotOctant) % 8];
813 break;
815 cursor = m_sizeCursors[(5 + rotOctant) % 8];
816 cornerHandle = true;
817 break;
819 cursor = m_sizeCursors[(6 + rotOctant) % 8];
820 break;
822 cursor = m_sizeCursors[(7 + rotOctant) % 8];
823 cornerHandle = true;
824 break;
826 cursor = Qt::SizeAllCursor;
827 statusText = i18n("Click and drag to move selection.");
828 break;
829 }
830 if (cornerHandle) {
831 statusText = i18n("Click and drag to resize selection. Middle click to set highlighted position.");
832 }
833 }
834 if (!editable) {
835 cursor = Qt::ArrowCursor;
836 }
837 } else {
838 // there used to be guides... :'''(
839 }
841 if (currentStrategy() == 0) {
842 Q_EMIT statusTextChanged(statusText);
843 }
844}
qreal rotationOfHandle(KoFlake::SelectionHandle handle, bool useEdgeRotation)
Returns rotation angle of given handle of the current selection.
QCursor cursor() const
return the last emitted cursor
void statusTextChanged(const QString &statusText)

References KoFlake::BottomLeftHandle, KoFlake::BottomMiddleHandle, KoFlake::BottomRightHandle, KoInteractionTool::currentStrategy(), KoToolBase::cursor(), koSelection(), KoFlake::LeftMiddleHandle, m_angle, m_lastHandle, m_mouseWasInsideHandles, m_rotateCursors, m_shearCursors, m_sizeCursors, KoFlake::NoHandle, KoFlake::RightMiddleHandle, rotationOfHandle(), selection(), KoToolBase::statusTextChanged(), KoFlake::TopLeftHandle, KoFlake::TopMiddleHandle, KoFlake::TopRightHandle, KoInteractionTool::tryUseCustomCursor(), and KoToolBase::useCursor().

◆ updateDistinctiveActions()

void DefaultTool::updateDistinctiveActions ( const QList< KoShape * > & editableShapes)
protectedvirtual

Enable/disable actions specific to the tool (vector vs. reference images)

Reimplemented in ToolReferenceImages.

Definition at line 1857 of file DefaultTool.cpp.

1857 {
1858 const bool multipleSelected = editableShapes.size() > 1;
1859
1860 action("object_group")->setEnabled(multipleSelected);
1861
1862 action("object_unite")->setEnabled(multipleSelected);
1863 action("object_intersect")->setEnabled(multipleSelected);
1864 action("object_subtract")->setEnabled(multipleSelected);
1865
1866 bool hasShapesWithMultipleSegments = false;
1867 Q_FOREACH (KoShape *shape, editableShapes) {
1868 KoPathShape *pathShape = dynamic_cast<KoPathShape *>(shape);
1869 if (pathShape && pathShape->subpathCount() > 1) {
1870 hasShapesWithMultipleSegments = true;
1871 break;
1872 }
1873 }
1874 action("object_split")->setEnabled(hasShapesWithMultipleSegments);
1875
1876
1877 bool hasGroupShape = false;
1878 foreach (KoShape *shape, editableShapes) {
1879 if (dynamic_cast<KoShapeGroup *>(shape)) {
1880 hasGroupShape = true;
1881 break;
1882 }
1883 }
1884 action("object_ungroup")->setEnabled(hasGroupShape);
1885
1886 bool enablePreformatted = false;
1887 bool enablePrePositioned = false;
1888 bool enableInlineWrapped = false;
1889 Q_FOREACH (KoShape *shape, editableShapes) {
1890 KoSvgTextShape *textShape = dynamic_cast<KoSvgTextShape *>(shape);
1891 if (textShape) {
1892 if (textShape->textType() != KoSvgTextShape::PreformattedText && !enablePreformatted) {
1893 enablePreformatted = true;
1894 }
1895 if (textShape && textShape->textType() != KoSvgTextShape::PrePositionedText && !enablePrePositioned) {
1896 enablePrePositioned = true;
1897 }
1898 if (textShape && textShape->textType() != KoSvgTextShape::PrePositionedText && !enableInlineWrapped) {
1899 enableInlineWrapped = true;
1900 }
1901 }
1902 }
1903 action("text_type_preformatted")->setEnabled(enablePreformatted);
1904 action("text_type_pre_positioned")->setEnabled(enablePrePositioned);
1905 action("text_type_inline_wrap")->setEnabled(enableInlineWrapped);
1906}
int subpathCount() const
Returns the number of subpaths in the path.

References KoToolBase::action(), KoSvgTextShape::PreformattedText, KoSvgTextShape::PrePositionedText, KoPathShape::subpathCount(), and KoSvgTextShape::textType().

◆ wantsAutoScroll()

bool DefaultTool::wantsAutoScroll ( ) const
overridevirtual

Return if dragging (moving with the mouse down) to the edge of a canvas should scroll the canvas (default is true).

Returns
if this tool wants mouse events to cause scrolling of canvas.

Reimplemented from KoToolBase.

Definition at line 551 of file DefaultTool.cpp.

552{
553 return true;
554}

Friends And Related Symbol Documentation

◆ SelectionHandler

friend class SelectionHandler
friend

Definition at line 198 of file DefaultTool.h.

◆ SelectionInteractionStrategy

friend class SelectionInteractionStrategy
friend

Definition at line 145 of file DefaultTool.h.

Member Data Documentation

◆ m_alignSignalsMapper

KisSignalMapper* DefaultTool::m_alignSignalsMapper {0}
private

Definition at line 202 of file DefaultTool.h.

202{0};

◆ m_angle

qreal DefaultTool::m_angle
private

Definition at line 196 of file DefaultTool.h.

◆ m_booleanSignalsMapper

KisSignalMapper* DefaultTool::m_booleanSignalsMapper {0}
private

Definition at line 205 of file DefaultTool.h.

205{0};

◆ m_contextMenu

QScopedPointer<QMenu> DefaultTool::m_contextMenu
protected

Definition at line 156 of file DefaultTool.h.

◆ m_decorator

QScopedPointer<SelectionDecorator> DefaultTool::m_decorator
private

Definition at line 187 of file DefaultTool.h.

◆ m_distributeSignalsMapper

KisSignalMapper* DefaultTool::m_distributeSignalsMapper {0}
private

Definition at line 203 of file DefaultTool.h.

203{0};

◆ m_hotPosition

KoFlake::AnchorPosition DefaultTool::m_hotPosition
private

Definition at line 181 of file DefaultTool.h.

◆ m_hoveredMeshHandle

KoShapeMeshGradientHandles::Handle DefaultTool::m_hoveredMeshHandle
private

Definition at line 190 of file DefaultTool.h.

◆ m_lastHandle

KoFlake::SelectionHandle DefaultTool::m_lastHandle
private

Definition at line 180 of file DefaultTool.h.

◆ m_lastPoint

QPointF DefaultTool::m_lastPoint
private

Definition at line 185 of file DefaultTool.h.

◆ m_mouseWasInsideHandles

bool DefaultTool::m_mouseWasInsideHandles
private

Definition at line 182 of file DefaultTool.h.

◆ m_rotateCursors

QCursor DefaultTool::m_rotateCursors[8]
private

Definition at line 194 of file DefaultTool.h.

◆ m_selectedMeshHandle

KoShapeMeshGradientHandles::Handle DefaultTool::m_selectedMeshHandle
private

Definition at line 189 of file DefaultTool.h.

◆ m_selectionBox

QPointF DefaultTool::m_selectionBox[8]
private

Definition at line 183 of file DefaultTool.h.

◆ m_selectionHandler

KoToolSelection* DefaultTool::m_selectionHandler
private

Definition at line 197 of file DefaultTool.h.

◆ m_selectionOutline

QPolygonF DefaultTool::m_selectionOutline
private

Definition at line 184 of file DefaultTool.h.

◆ m_shearCursors

QCursor DefaultTool::m_shearCursors[8]
private

Definition at line 195 of file DefaultTool.h.

◆ m_sizeCursors

QCursor DefaultTool::m_sizeCursors[8]
private

Definition at line 193 of file DefaultTool.h.

◆ m_tabbedOptionWidget

DefaultToolTabbedWidget* DefaultTool::m_tabbedOptionWidget
private

Definition at line 200 of file DefaultTool.h.

◆ m_textPropertyInterface

DefaultToolTextPropertiesInterface* DefaultTool::m_textPropertyInterface {0}
private

Definition at line 208 of file DefaultTool.h.

208{0};

◆ m_textTypeSignalsMapper

KisSignalMapper* DefaultTool::m_textTypeSignalsMapper {0}
private

Definition at line 206 of file DefaultTool.h.

206{0};

◆ m_transformSignalsMapper

KisSignalMapper* DefaultTool::m_transformSignalsMapper {0}
private

Definition at line 204 of file DefaultTool.h.

204{0};

The documentation for this class was generated from the following files: