Warning, file /office/calligra/libs/flake/KoToolBase.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /* This file is part of the KDE project
0002  * Copyright (C) 2006 Thomas Zander <zander@kde.org>
0003  * Copyright (C) 2011 Jan Hambrecht <jaham@gmx.net>
0004  *
0005  * This library is free software; you can redistribute it and/or
0006  * modify it under the terms of the GNU Library General Public
0007  * License as published by the Free Software Foundation; either
0008  * version 2 of the License, or (at your option) any later version.
0009  *
0010  * This library is distributed in the hope that it will be useful,
0011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0013  * Library General Public License for more details.
0014  *
0015  * You should have received a copy of the GNU Library General Public License
0016  * along with this library; see the file COPYING.LIB.  If not, write to
0017  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0018  * Boston, MA 02110-1301, USA.
0019  */
0020 #ifndef KOTOOLBASE_H
0021 #define KOTOOLBASE_H
0022 
0023 #include <QObject>
0024 #include <QPointer>
0025 #include <QSet>
0026 #include <QList>
0027 #include <QHash>
0028 
0029 #include "flake_export.h"
0030 
0031 class KoShape;
0032 class KoCanvasBase;
0033 class KoPointerEvent;
0034 class KoViewConverter;
0035 class KoToolSelection;
0036 class KoToolBasePrivate;
0037 class KoShapeBasedDocumentBase;
0038 
0039 class QAction;
0040 class QAction;
0041 class QKeyEvent;
0042 class QWidget;
0043 class QCursor;
0044 class QPainter;
0045 class QString;
0046 class QStringList;
0047 class QRectF;
0048 class QPointF;
0049 class QInputMethodEvent;
0050 class QDragMoveEvent;
0051 class QDragLeaveEvent;
0052 class QDropEvent;
0053 class QTouchEvent;
0054 
0055 /**
0056  * Abstract base class for all tools. Tools can create or manipulate
0057  * flake shapes, canvas state or any other thing that a user may wish
0058  * to do to his document or his view on a document with a pointing
0059  * device.
0060  *
0061  * There exists an instance of every tool for every pointer device.
0062  * These instances are managed by the toolmanager..
0063  */
0064 class FLAKE_EXPORT KoToolBase : public QObject
0065 {
0066     Q_OBJECT
0067 public:
0068     /// Option for activate()
0069     enum ToolActivation {
0070         TemporaryActivation, ///< The tool is activated temporarily and works 'in-place' of another one.
0071         DefaultActivation   ///< The tool is activated normally and emitting 'done' goes to the defaultTool
0072     };
0073 
0074     /**
0075      * Constructor, normally only called by the factory (see KoToolFactoryBase)
0076      * @param canvas the canvas interface this tool will work for.
0077      */
0078     explicit KoToolBase(KoCanvasBase *canvas);
0079     ~KoToolBase() override;
0080 
0081     /**
0082      * connect the tool to the new shapecontroller. Old connections are removed.
0083      *
0084      * @param shapeController the new shape controller
0085      */
0086     void updateShapeController(KoShapeBasedDocumentBase *shapeController);
0087 
0088     /**
0089      * request a repaint of the decorations to be made. This triggers
0090      * an update call on the canvas, but does not paint directly.
0091      */
0092     virtual void repaintDecorations();
0093 
0094     /**
0095      * Return if dragging (moving with the mouse down) to the edge of a canvas should scroll the
0096      * canvas (default is true).
0097      * @return if this tool wants mouse events to cause scrolling of canvas.
0098      */
0099     virtual bool wantsAutoScroll() const;
0100 
0101     /**
0102      * Called by the canvas to paint any decorations that the tool deems needed.
0103      * The painter has the top left of the canvas as its origin.
0104      * @param painter used for painting the shape
0105      * @param converter to convert between internal and view coordinates.
0106      */
0107     virtual void paint(QPainter &painter, const KoViewConverter &converter) = 0;
0108 
0109     /**
0110      * Return the option widgets for this tool. Create them if they
0111      * do not exist yet. If the tool does not have an option widget,
0112      * this method return an empty list. (After discussion with Thomas, who prefers
0113      * the toolmanager to handle that case.)
0114      *
0115      * @see m_optionWidgets
0116      */
0117     QList<QPointer<QWidget> > optionWidgets();
0118 
0119     /**
0120      * Retrieves the entire collection of actions for the tool.
0121      */
0122     QHash<QString, QAction *> actions() const;
0123 
0124     /**
0125      * Retrieve an action by name.
0126      */
0127     QAction *action(const QString &name) const;
0128 
0129     /**
0130      * Called when (one of) the mouse or stylus buttons is pressed.
0131      * Implementors should call event->ignore() if they do not actually use the event.
0132      * @param event state and reason of this mouse or stylus press
0133      */
0134     virtual void mousePressEvent(KoPointerEvent *event) = 0;
0135 
0136     /**
0137      * Called when (one of) the mouse or stylus buttons is double clicked.
0138      * Implementors should call event->ignore() if they do not actually use the event.
0139      * Default implementation ignores this event.
0140      * @param event state and reason of this mouse or stylus press
0141      */
0142     virtual void mouseDoubleClickEvent(KoPointerEvent *event);
0143 
0144     /**
0145      * Called when (one of) the mouse or stylus buttons is triple clicked.
0146      * Implementors should call event->ignore() if they do not actually use the event.
0147      * Default implementation ignores this event.
0148      * @param event state and reason of this mouse or stylus press
0149      */
0150     virtual void mouseTripleClickEvent(KoPointerEvent *event);
0151 
0152     /**
0153      * Called when the mouse or stylus moved over the canvas.
0154      * Implementors should call event->ignore() if they do not actually use the event.
0155      * @param event state and reason of this mouse or stylus move
0156      */
0157     virtual void mouseMoveEvent(KoPointerEvent *event) = 0;
0158 
0159     /**
0160      * Called when (one of) the mouse or stylus buttons is released.
0161      * Implementors should call event->ignore() if they do not actually use the event.
0162      * @param event state and reason of this mouse or stylus release
0163      */
0164     virtual void mouseReleaseEvent(KoPointerEvent *event) = 0;
0165 
0166     /**
0167      * Called when a key is pressed, before shortcuts are triggered.
0168      * Implementors should call event->accept() if they do want this shortcut to
0169      * be handled by keyPressEvent rather than by a more global shortcut.
0170      * Default implementation ignores this event.
0171      * @param event state and reason of this key press
0172      */
0173     virtual void shortcutOverrideEvent(QKeyEvent *event);
0174 
0175     /**
0176      * Called when a key is pressed.
0177      * Implementors should call event->ignore() if they do not actually use the event.
0178      * Default implementation ignores this event.
0179      * @param event state and reason of this key press
0180      */
0181     virtual void keyPressEvent(QKeyEvent *event);
0182 
0183     /**
0184      * Called when a key is released
0185      * Implementors should call event->ignore() if they do not actually use the event.
0186      * Default implementation ignores this event.
0187      * @param event state and reason of this key release
0188      */
0189     virtual void keyReleaseEvent(QKeyEvent *event);
0190 
0191     /**
0192      * Called when the scrollwheel is used
0193      * Implementors should call event->ignore() if they do not actually use the event
0194      * @param event state of this wheel event
0195      */
0196     virtual void wheelEvent(KoPointerEvent *event);
0197 
0198     virtual void touchEvent(QTouchEvent *event);
0199 
0200     /**
0201      * This method is used to query a set of properties of the tool to be
0202      * able to support complex input method operations as support for surrounding
0203      * text and reconversions.
0204      * Default implementation returns simple defaults, for tools that want to provide
0205      * a more responsive text entry experience for CJK languages it would be good to reimplemnt.
0206      * @param query specifies which property is queried.
0207      * @param converter the view converter for the current canvas.
0208      */
0209     virtual QVariant inputMethodQuery(Qt::InputMethodQuery query, const KoViewConverter &converter) const;
0210 
0211     /**
0212      * Text entry of complex text, like CJK, can be made more interactive if a tool
0213      * implements this and the InputMethodQuery() methods.
0214      * Reimplementing this only provides the user with a more responsive text experience, since the
0215      * default implementation forwards the typed text as key pressed events.
0216      * @param event the input method event.
0217      */
0218     virtual void inputMethodEvent(QInputMethodEvent *event);
0219 
0220     /**
0221      * Called when (one of) a custom device buttons is pressed.
0222      * Implementors should call event->ignore() if they do not actually use the event.
0223      * @param event state and reason of this custom device press
0224      */
0225     virtual void customPressEvent(KoPointerEvent *event);
0226 
0227     /**
0228      * Called when (one of) a custom device buttons is released.
0229      * Implementors should call event->ignore() if they do not actually use the event.
0230      * @param event state and reason of this custom device release
0231      */
0232     virtual void customReleaseEvent(KoPointerEvent *event);
0233 
0234     /**
0235      * Called when a custom device moved over the canvas.
0236      * Implementors should call event->ignore() if they do not actually use the event.
0237      * @param event state and reason of this custom device move
0238      */
0239     virtual void customMoveEvent(KoPointerEvent *event);
0240 
0241     virtual bool wantsTouch() const;
0242 
0243     /**
0244      * Set the identifier code from the KoToolFactoryBase that created this tool.
0245      * @param id the identifier code
0246      * @see KoToolFactoryBase::id()
0247      */
0248     void setToolId(const QString &id);
0249 
0250     /**
0251      * get the identifier code from the KoToolFactoryBase that created this tool.
0252      * @return the toolId.
0253      * @see KoToolFactoryBase::id()
0254      */
0255     Q_INVOKABLE QString toolId() const;
0256 
0257     /// return the last emitted cursor
0258     QCursor cursor() const;
0259 
0260     /**
0261      * Returns the internal selection object of this tool.
0262      * Each tool can have a selection which is private to that tool and the specified shape that it comes with.
0263      * The default returns 0.
0264      */
0265     virtual KoToolSelection *selection();
0266 
0267     /**
0268      * @returns true if the tool has selected data.
0269      */
0270     virtual bool hasSelection();
0271 
0272     /**
0273      * copies the tools selection to the clipboard.
0274      * The default implementation is empty to aid tools that don't have any selection.
0275      * @see selection()
0276      */
0277     virtual void copy() const;
0278 
0279     /**
0280      * Delete the tools selection.
0281      * The default implementation is empty to aid tools that don't have any selection.
0282      * @see selection()
0283      */
0284     virtual void deleteSelection();
0285 
0286     /**
0287      * Cut the tools selection and copy it to the clipboard.
0288      * The default implementation calls copy() and then deleteSelection()
0289      * @see copy()
0290      * @see deleteSelection()
0291      */
0292     virtual void cut();
0293 
0294     /**
0295      * Paste the clipboard selection.
0296      * A tool typically has one or more shapes selected and pasting should do something meaningful
0297      * for this specific shape and tool combination.  Inserting text in a text tool, for example.
0298      * If you reimplement this function make sure to also reimplement supportedPasteMimeTypes().
0299      * @return will return true if pasting succeeded. False if nothing happened.
0300      */
0301     virtual bool paste();
0302 
0303     /**
0304      * Returns the mimetypes that this tool's paste() function can handle
0305      * @return QStringList containing the mimetypes that's supported by paste()
0306      */
0307     virtual QStringList supportedPasteMimeTypes() const;
0308 
0309     /**
0310      * Handle the dragMoveEvent
0311      * A tool typically has one or more shapes selected and dropping into should do
0312      * something meaningful for this specific shape and tool combination. For example
0313      * dropping text in a text tool.
0314      * The tool should Accept the event if it is meaningful; Default implementation does not.
0315      */
0316     virtual void dragMoveEvent(QDragMoveEvent *event, const QPointF &point);
0317 
0318     /**
0319      * Handle the dragLeaveEvent
0320      * Basically just a notification that the drag is no long relevant
0321      * The tool should Accept the event if it is meaningful; Default implementation does not.
0322      */
0323     virtual void dragLeaveEvent(QDragLeaveEvent *event);
0324 
0325     /**
0326      * Handle the dropEvent
0327      * A tool typically has one or more shapes selected and dropping into should do
0328      * something meaningful for this specific shape and tool combination. For example
0329      * dropping text in a text tool.
0330      * The tool should Accept the event if it is meaningful; Default implementation does not.
0331      */
0332     virtual void dropEvent(QDropEvent *event, const QPointF &point);
0333 
0334     /**
0335      * @return A list of actions to be used for a popup.
0336      */
0337     QList<QAction*> popupActionList() const;
0338 
0339     /// Returns the canvas the tool is working on
0340     KoCanvasBase *canvas() const;
0341 
0342     /**
0343       * This method can be reimplemented in a subclass.
0344       * @return returns true, if the tool is in text mode. that means, that there is
0345       *   any kind of textual input and all single key shortcuts should be eaten.
0346       */
0347     bool isInTextMode() const;
0348 
0349 public Q_SLOTS:
0350 
0351     /**
0352      * This method is called when this tool instance is activated.
0353      * For any main window there is only one tool active at a time, which then gets all
0354      * user input.  Switching between tools will call deactivate on one and activate on the
0355      * new tool allowing the tool to flush items (like a selection)
0356      * when it is not in use.
0357      *
0358      * <p>There is one case where two tools are activated at the same.  This is the case
0359      * where one tool delegates work to another temporarily.  For example, while shift is
0360      * being held down.  The second tool will get activated with temporary=true and
0361      * it should emit done() when the state that activated it is ended.
0362      * <p>One of the important tasks of activate is to call useCursor()
0363      *
0364      * @param shapes the set of shapes that are selected or suggested for editing by a
0365      *      selected shape for the tool to work on.  Not all shapes will be meant for this
0366      *      tool.
0367      * @param toolActivation if TemporaryActivation, this tool is only temporarily activated
0368      *                  and should emit done when it is done.
0369      * @see deactivate()
0370      */
0371     virtual void activate(ToolActivation toolActivation, const QSet<KoShape*> &shapes) = 0;
0372 
0373     /**
0374      * This method is called whenever this tool is no longer the
0375      * active tool
0376      * @see activate()
0377      */
0378     virtual void deactivate();
0379 
0380     /**
0381      * This method is called whenever a property in the resource
0382      * provider associated with the canvas this tool belongs to
0383      * changes. An example is currently selected foreground color.
0384      */
0385     virtual void canvasResourceChanged(int key, const QVariant &res);
0386 
0387     /**
0388      * This method is called whenever a property in the resource
0389      * provider associated with the document this tool belongs to
0390      * changes. An example is the handle radius
0391      */
0392     virtual void documentResourceChanged(int key, const QVariant &res);
0393 
0394     /**
0395      * This method just relays the given text via the tools statusTextChanged signal.
0396      * @param statusText the new status text
0397      */
0398     void setStatusText(const QString &statusText);
0399 
0400 Q_SIGNALS:
0401 
0402     /**
0403      * Emitted when this tool wants itself to be replaced by another tool.
0404      *
0405      * @param id the identification of the desired tool
0406      * @see toolId(), KoToolFactoryBase::id()
0407      */
0408     void activateTool(const QString &id);
0409 
0410     /**
0411      * Emitted when this tool wants itself to temporarily be replaced by another tool.
0412      * For instance, a paint tool could desire to be
0413      * temporarily replaced by a pan tool which could be temporarily
0414      * replaced by a colorpicker.
0415      * @param id the identification of the desired tool
0416      */
0417     void activateTemporary(const QString &id);
0418 
0419     /**
0420      * Emitted when the tool has been temporarily activated and wants
0421      * to notify the world that it's done.
0422      */
0423     void done();
0424 
0425     /**
0426      * Emitted by useCursor() when the cursor to display on the canvas is changed.
0427      * The KoToolManager should connect to this signal to handle cursors further.
0428      */
0429     void cursorChanged(const QCursor &cursor);
0430 
0431     /**
0432      * A tool can have a selection that is copy-able, this signal is emitted when that status changes.
0433      * @param hasSelection is true when the tool holds selected data.
0434      */
0435     void selectionChanged(bool hasSelection);
0436 
0437     /**
0438      * Emitted when the tool wants to display a different status text
0439      * @param statusText the new status text
0440      */
0441     void statusTextChanged(const QString &statusText);
0442 
0443 protected:
0444     /**
0445      * Classes inheriting from this one can call this method to signify which cursor
0446      * the tool wants to display at this time.  Logical place to call it is after an
0447      * incoming event has been handled.
0448      * @param cursor the new cursor.
0449      */
0450     void useCursor(const QCursor &cursor);
0451 
0452     /**
0453      * Reimplement this if your tool actually has an option widget.
0454      * Sets the option widget to 0 by default.
0455      */
0456     virtual QWidget *createOptionWidget();
0457     virtual QList<QPointer<QWidget> > createOptionWidgets();
0458 
0459     /**
0460      * Add an action under the given name to the collection.
0461      *
0462      * Inserting an action under a name that is already used for another action will replace
0463      * the other action in the collection.
0464      *
0465      * @param name The name by which the action be retrieved again from the collection.
0466      * @param action The action to add.
0467      */
0468     void addAction(const QString &name, QAction *action);
0469 
0470     /**
0471      * Set the list of actions to be used as popup menu.
0472      * @param list the list of actions.
0473      * @see popupActionList
0474      */
0475     void setPopupActionList(const QList<QAction*> &list);
0476 
0477     /// Convenience function to get the current handle radius
0478     uint handleRadius() const;
0479 
0480     /// Convenience function to get the current grab sensitivity
0481     uint grabSensitivity() const;
0482 
0483     /**
0484     * Returns a handle grab rect at the given position.
0485     *
0486     * The position is expected to be in document coordinates. The grab sensitivity
0487     * canvas resource is used for the dimension of the rectangle.
0488     *
0489     * @return the handle rectangle in document coordinates
0490     */
0491     QRectF handleGrabRect(const QPointF &position) const;
0492 
0493     /**
0494     * Returns a handle paint rect at the given position.
0495     *
0496     * The position is expected to be in document coordinates. The handle radius
0497     * canvas resource is used for the dimension of the rectangle.
0498     *
0499     * @return the handle rectangle in document coordinates
0500     */
0501     QRectF handlePaintRect(const QPointF &position) const;
0502 
0503     /**
0504       * You should set the text mode to true in subclasses, if this tool is in text input mode, eg if the users
0505       * are able to type. If you don't set it, then single key shortcuts will get the key event and not this tool.
0506       */
0507     void setTextMode(bool value);
0508 
0509 protected:
0510     KoToolBase(KoToolBasePrivate &dd);
0511 
0512     KoToolBasePrivate *d_ptr;
0513 
0514 
0515 private:
0516     KoToolBase();
0517     KoToolBase(const KoToolBase&);
0518     KoToolBase& operator=(const KoToolBase&);
0519 
0520     Q_DECLARE_PRIVATE(KoToolBase)
0521 };
0522 
0523 #endif /* KOTOOL_H */