File indexing completed on 2024-05-19 05:54:10

0001 /*
0002     SPDX-FileCopyrightText: 2007-2008 Robert Knight <robertknight@gmail.com>
0003     SPDX-FileCopyrightText: 2020 Tomaz Canabrava <tcanabrava@gmail.com>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #ifndef HOTSPOT
0009 #define HOTSPOT
0010 
0011 #include <QObject>
0012 
0013 #include "konsoleprivate_export.h"
0014 #include <QList>
0015 #include <QRect>
0016 #include <QRegion>
0017 #include <QSharedPointer>
0018 
0019 class QAction;
0020 class QMenu;
0021 class QMouseEvent;
0022 class QKeyEvent;
0023 
0024 namespace Konsole
0025 {
0026 class TerminalDisplay;
0027 
0028 /**
0029  * Represents an area of text which matched the pattern a particular filter has been looking for.
0030  *
0031  * Each hotspot has a type identifier associated with it ( such as a link or a highlighted section ),
0032  * and an action.  When the user performs some activity such as a mouse-click in a hotspot area ( the exact
0033  * action will depend on what is displaying the block of text which the filter is processing ), the hotspot's
0034  * activate() method should be called.  Depending on the type of hotspot this will trigger a suitable response.
0035  *
0036  * For example, if a hotspot represents a URL then a suitable action would be opening that URL in a web browser.
0037  * Hotspots may have more than one action, in which case the list of actions can be obtained using the
0038  * actions() method.  These actions may then be displayed in a popup menu or toolbar for example.
0039  */
0040 class KONSOLEPRIVATE_EXPORT HotSpot : public QObject
0041 {
0042     // krazy suggest using Q_OBJECT here but moc can not handle
0043     // nested classes
0044     // QObject derived classes should use the Q_OBJECT macro
0045 
0046 public:
0047     /**
0048      * Constructs a new hotspot which covers the area from (@p startLine,@p startColumn) to (@p endLine,@p endColumn)
0049      * in a block of text.
0050      */
0051     HotSpot(int startLine, int startColumn, int endLine, int endColumn);
0052     ~HotSpot() override;
0053 
0054     enum Type {
0055         // the type of the hotspot is not specified
0056         NotSpecified,
0057         // this hotspot rpresents a file on the filesystem
0058         File,
0059         // this hotspot represents a clickable URL link
0060         Link,
0061         // this hotspot represents a clickable e-mail address
0062         EMailAddress,
0063         // this hotspot represents a marker
0064         Marker,
0065         // this spot represents a Escaped URL
0066         EscapedUrl,
0067         // this hotspot represents a color of text
0068         Color,
0069     };
0070 
0071     /** Returns the line when the hotspot area starts */
0072     int startLine() const;
0073     /** Returns the line where the hotspot area ends */
0074     int endLine() const;
0075     /** Returns the column on startLine() where the hotspot area starts */
0076     int startColumn() const;
0077     /** Returns the column on endLine() where the hotspot area ends */
0078     int endColumn() const;
0079     /**
0080      * Returns the type of the hotspot.  This is usually used as a hint for views on how to represent
0081      * the hotspot graphically.  eg.  Link hotspots are typically underlined when the user mouses over them
0082      */
0083     Type type() const;
0084     /**
0085      * Causes the action associated with a hotspot to be triggered.
0086      *
0087      * @param object The object which caused the hotspot to be triggered.  This is
0088      * typically null ( in which case the default action should be performed ) or
0089      * one of the objects from the actions() list.  In which case the associated
0090      * action should be performed.
0091      */
0092     virtual void activate(QObject *object = nullptr) = 0;
0093     /**
0094      * Returns a list of actions associated with the hotspot which can be used in a
0095      * menu or toolbar
0096      */
0097     virtual QList<QAction *> actions();
0098 
0099     virtual bool hasDragOperation() const;
0100     virtual void startDrag();
0101 
0102     /**
0103      * Sets a menu up with actions for the hotspot.
0104      *
0105      * Returns a list of the added actions (useful for removing e.g.
0106      * the open-with actions before adding new ones to prevent duplicate
0107      * open-with actions being shown in @p menu).
0108      *
0109      * The base implementation does nothing.
0110      */
0111     virtual QList<QAction *> setupMenu(QMenu *menu);
0112 
0113     QPair<QRegion, QRect> region(int fontWidth, int fontHeight, int columns, QRect terminalDisplayRect) const;
0114 
0115     /**
0116      * Returns true if the type of the HotSpot is Link, EMailAddress, or EscapedUrl, (see
0117      * Type enum), otherwise returns false; mainly used in the input events, e.g. to not
0118      * change the shape of the mouse pointer to a pointing hand if the HotSpot doesn't
0119      * represent a clickable URI.
0120      */
0121     bool isUrl();
0122 
0123     /** The base implementation does nothing */
0124     virtual void mouseMoveEvent(TerminalDisplay *td, QMouseEvent *ev);
0125 
0126     /**
0127      * The mouse pointer shape is changed to a pointing hand; also because the underline
0128      * is painted under the link, update() is called on the TerminalDisplay widget.
0129      */
0130     virtual void mouseEnterEvent(TerminalDisplay *td, QMouseEvent *ev);
0131 
0132     /**
0133      * The mouse pointer is reset to the default shape, see TerminalDisplay::resetCursor();
0134      * also because the underline is hidden from under the link, update() is called on the
0135      * TerminalDisplay widget.
0136      */
0137     virtual void mouseLeaveEvent(TerminalDisplay *td, QMouseEvent *ev);
0138 
0139     /**
0140      * If the Ctrl key is pressed or TerminalDisplay::openLinksByDirectClick() is
0141      * true, the activate() method is called to handle/open the link, see activate().
0142      */
0143     virtual void mouseReleaseEvent(TerminalDisplay *td, QMouseEvent *ev);
0144 
0145     /**
0146      * If the Ctrl key is pressed, the mouse pointer shape is changed to a pointing hand.
0147      *
0148      * Note that if TerminalDisplay::openLinksByDirectClick() is true the mouse pointer shape is always
0149      * changed to a pointing hand when hovering over a link, regardless of the state of the Ctrl key.
0150      */
0151     virtual void keyPressEvent(TerminalDisplay *td, QKeyEvent *ev);
0152 
0153     /**
0154      * This resets the mouse pointer to the default shape (if e.g. the Ctrl key had been pressed
0155      * and now has been released).
0156      *
0157      * Note that if TerminalDisplay::openLinksByDirectClick() is true the mouse pointer shape is always
0158      * changed to a pointing hand when hovering over a link, regardless of the state of the Ctrl key.
0159      */
0160     virtual void keyReleaseEvent(TerminalDisplay *, QKeyEvent *ev);
0161 
0162     void debug();
0163 
0164 protected:
0165     /** Sets the type of a hotspot.  This should only be set once */
0166     void setType(Type type);
0167 
0168 private:
0169     int _startLine;
0170     int _startColumn;
0171     int _endLine;
0172     int _endColumn;
0173     Type _type;
0174     QRegion _mouseOverHotspotArea;
0175 };
0176 
0177 }
0178 
0179 #endif