File indexing completed on 2024-05-19 05:28:21

0001 /*
0002     SPDX-FileCopyrightText: 2007-2008 Robert Knight <robertknight@gmail.com>
0003     SPDX-FileCopyrightText: 1997, 1998 Lars Doelle <lars.doelle@on-line.de>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 
0007     This program is distributed in the hope that it will be useful,
0008     but WITHOUT ANY WARRANTY; without even the implied warranty of
0009     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0010     GNU General Public License for more details.
0011 
0012     You should have received a copy of the GNU General Public License
0013     along with this program; if not, write to the Free Software
0014     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
0015     02110-1301  USA.
0016 */
0017 
0018 #ifndef TERMINALDISPLAY_H
0019 #define TERMINALDISPLAY_H
0020 
0021 // Qt
0022 #include <QColor>
0023 #include <QPointer>
0024 // #include <QWidget>
0025 #include <QQuickPaintedItem>
0026 
0027 // Konsole
0028 #include "Character.h"
0029 #include "Filter.h"
0030 #include "qtermwidget.h"
0031 // #include "konsole_export.h"
0032 #define KONSOLEPRIVATE_EXPORT
0033 
0034 // QMLTermWidget
0035 #include "ColorScheme.h"
0036 #include "TerminalSession.h"
0037 
0038 class QDrag;
0039 class QDragEnterEvent;
0040 class QDropEvent;
0041 class QLabel;
0042 class QTimer;
0043 class QEvent;
0044 class QGridLayout;
0045 class QKeyEvent;
0046 class QScrollBar;
0047 class QShowEvent;
0048 class QHideEvent;
0049 class QTimerEvent;
0050 class QWidget;
0051 
0052 // class KMenu;
0053 
0054 namespace Konsole
0055 {
0056 
0057 enum MotionAfterPasting {
0058     // No move screenwindow after pasting
0059     NoMoveScreenWindow = 0,
0060     // Move start of screenwindow after pasting
0061     MoveStartScreenWindow = 1,
0062     // Move end of screenwindow after pasting
0063     MoveEndScreenWindow = 2
0064 };
0065 
0066 struct CharPos {
0067     int columns;
0068     int lines;
0069 
0070     operator QPoint()
0071     {
0072         return QPoint{columns, lines};
0073     }
0074 };
0075 
0076 extern unsigned short vt100_graphics[32];
0077 
0078 class ScreenWindow;
0079 
0080 /**
0081  * A widget which displays output from a terminal emulation and sends input keypresses and mouse activity
0082  * to the terminal.
0083  *
0084  * When the terminal emulation receives new output from the program running in the terminal,
0085  * it will update the display by calling updateImage().
0086  *
0087  * TODO More documentation
0088  */
0089 class KONSOLEPRIVATE_EXPORT TerminalDisplay : public QQuickPaintedItem
0090 {
0091     Q_OBJECT
0092 
0093     Q_PROPERTY(TerminalSession *session READ getSession WRITE setSession NOTIFY sessionChanged)
0094     Q_PROPERTY(QFont font READ getVTFont WRITE setVTFont NOTIFY vtFontChanged)
0095     Q_PROPERTY(QString colorScheme READ colorScheme WRITE setColorScheme NOTIFY colorSchemeChanged)
0096     Q_PROPERTY(QSize terminalSize READ getTerminalSize NOTIFY changedContentSizeSignal)
0097     Q_PROPERTY(int lineSpacing READ lineSpacing WRITE setLineSpacing NOTIFY lineSpacingChanged)
0098     Q_PROPERTY(bool terminalUsesMouse READ getUsesMouse NOTIFY usesMouseChanged)
0099     Q_PROPERTY(int lines READ lines NOTIFY changedContentSizeSignal)
0100     Q_PROPERTY(int columns READ columns NOTIFY changedContentSizeSignal)
0101     Q_PROPERTY(int scrollbarCurrentValue READ getScrollbarValue NOTIFY scrollbarParamsChanged)
0102     Q_PROPERTY(int scrollbarMaximum READ getScrollbarMaximum NOTIFY scrollbarParamsChanged)
0103     Q_PROPERTY(int scrollbarMinimum READ getScrollbarMinimum NOTIFY scrollbarParamsChanged)
0104     Q_PROPERTY(QSize fontMetrics READ getFontMetrics NOTIFY changedFontMetricSignal)
0105 
0106     Q_PROPERTY(bool enableBold READ getBoldIntense WRITE setBoldIntense NOTIFY boldIntenseChanged)
0107     Q_PROPERTY(bool fullCursorHeight READ fullCursorHeight WRITE setFullCursorHeight NOTIFY fullCursorHeightChanged)
0108     Q_PROPERTY(bool blinkingCursor READ blinkingCursor WRITE setBlinkingCursor NOTIFY blinkingCursorStateChanged)
0109     Q_PROPERTY(bool antialiasText READ antialias WRITE setAntialias)
0110     Q_PROPERTY(QStringList availableColorSchemes READ availableColorSchemes NOTIFY availableColorSchemesChanged)
0111     Q_PROPERTY(qreal backgroundOpacity READ opacity WRITE setOpacity NOTIFY opacityChanged)
0112 
0113 public:
0114     /** Constructs a new terminal display widget with the specified parent. */
0115     TerminalDisplay(QQuickItem *parent = nullptr);
0116     ~TerminalDisplay() override;
0117 
0118     /** Returns the terminal color palette used by the display. */
0119     std::span<const ColorEntry> colorTable() const;
0120 
0121     /** Sets the terminal color palette used by the display. */
0122     void setColorTable(std::array<ColorEntry, TABLE_COLORS> &&table);
0123 
0124     /**
0125      * Sets the seed used to generate random colors for the display
0126      * (in color schemes that support them).
0127      */
0128 
0129     void setRandomSeed(uint seed);
0130     /**
0131      * Returns the seed used to generate random colors for the display
0132      * (in color schemes that support them).
0133      */
0134     uint randomSeed() const;
0135 
0136     /** Sets the opacity of the terminal display. */
0137     void setOpacity(qreal opacity);
0138 
0139     /**
0140      * This enum describes the location where the scroll bar is positioned in the display widget.
0141      */
0142     enum ScrollBarPosition {
0143         /** Do not show the scroll bar. */
0144         NoScrollBar = 0,
0145         /** Show the scroll bar on the left side of the display. */
0146         ScrollBarLeft = 1,
0147         /** Show the scroll bar on the right side of the display. */
0148         ScrollBarRight = 2
0149     };
0150 
0151     /**
0152      * Specifies whether the terminal display has a vertical scroll bar, and if so whether it
0153      * is shown on the left or right side of the display.
0154      */
0155     void setScrollBarPosition(QTermWidget::ScrollBarPosition position);
0156 
0157     /**
0158      * Sets the current position and range of the display's scroll bar.
0159      *
0160      * @param cursor The position of the scroll bar's thumb.
0161      * @param lines The maximum value of the scroll bar.
0162      */
0163     void setScroll(int cursor, int lines);
0164 
0165     /**
0166      * Scroll to the bottom of the terminal (reset scrolling).
0167      */
0168     void scrollToEnd();
0169 
0170     /**
0171      * Returns the display's filter chain.  When the image for the display is updated,
0172      * the text is passed through each filter in the chain.  Each filter can define
0173      * hotspots which correspond to certain strings (such as URLs or particular words).
0174      * Depending on the type of the hotspots created by the filter ( returned by Filter::Hotspot::type() )
0175      * the view will draw visual cues such as underlines on mouse-over for links or translucent
0176      * rectangles for markers.
0177      *
0178      * To add a new filter to the view, call:
0179      *      viewWidget->filterChain()->addFilter( filterObject );
0180      */
0181     FilterChain *filterChain() const;
0182 
0183     /**
0184      * Updates the filters in the display's filter chain.  This will cause
0185      * the hotspots to be updated to match the current image.
0186      *
0187      * WARNING:  This function can be expensive depending on the
0188      * image size and number of filters in the filterChain()
0189      *
0190      * TODO - This API does not really allow efficient usage.  Revise it so
0191      * that the processing can be done in a better way.
0192      *
0193      * eg:
0194      *      - Area of interest may be known ( eg. mouse cursor hovering
0195      *      over an area )
0196      */
0197     void processFilters();
0198 
0199     /**
0200      * Returns a list of menu actions created by the filters for the content
0201      * at the given @p position.
0202      */
0203     QList<QAction *> filterActions(const QPoint &position);
0204 
0205     /** Returns true if the cursor is set to blink or false otherwise. */
0206     bool blinkingCursor()
0207     {
0208         return _hasBlinkingCursor;
0209     }
0210     /** Specifies whether or not the cursor blinks. */
0211     void setBlinkingCursor(bool blink);
0212 
0213     /** Specifies whether or not text can blink. */
0214     void setBlinkingTextEnabled(bool blink);
0215 
0216     void setCtrlDrag(bool enable)
0217     {
0218         _ctrlDrag = enable;
0219     }
0220     bool ctrlDrag()
0221     {
0222         return _ctrlDrag;
0223     }
0224 
0225     /**
0226      *  This enum describes the methods for selecting text when
0227      *  the user triple-clicks within the display.
0228      */
0229     enum TripleClickMode {
0230         /** Select the whole line underneath the cursor. */
0231         SelectWholeLine,
0232         /** Select from the current cursor position to the end of the line. */
0233         SelectForwardsFromCursor
0234     };
0235     /** Sets how the text is selected when the user triple clicks within the display. */
0236     void setTripleClickMode(TripleClickMode mode)
0237     {
0238         _tripleClickMode = mode;
0239     }
0240     /** See setTripleClickSelectionMode() */
0241     TripleClickMode tripleClickMode()
0242     {
0243         return _tripleClickMode;
0244     }
0245 
0246     void setLineSpacing(uint);
0247     void setMargin(int);
0248 
0249     int margin() const;
0250     uint lineSpacing() const;
0251 
0252     void emitSelection(bool useXselection, bool appendReturn);
0253 
0254     /** change and wrap text corresponding to paste mode **/
0255     void bracketText(QString &text) const;
0256 
0257     /**
0258      * Sets the shape of the keyboard cursor.  This is the cursor drawn
0259      * at the position in the terminal where keyboard input will appear.
0260      *
0261      * In addition the terminal display widget also has a cursor for
0262      * the mouse pointer, which can be set using the QWidget::setCursor()
0263      * method.
0264      *
0265      * Defaults to BlockCursor
0266      */
0267     void setKeyboardCursorShape(Emulation::KeyboardCursorShape shape);
0268     /**
0269      * Returns the shape of the keyboard cursor.  See setKeyboardCursorShape()
0270      */
0271     Emulation::KeyboardCursorShape keyboardCursorShape() const;
0272 
0273     /**
0274      * Sets the color used to draw the keyboard cursor.
0275      *
0276      * The keyboard cursor defaults to using the foreground color of the character
0277      * underneath it.
0278      *
0279      * @param useForegroundColor If true, the cursor color will change to match
0280      * the foreground color of the character underneath it as it is moved, in this
0281      * case, the @p color parameter is ignored and the color of the character
0282      * under the cursor is inverted to ensure that it is still readable.
0283      * @param color The color to use to draw the cursor.  This is only taken into
0284      * account if @p useForegroundColor is false.
0285      */
0286     void setKeyboardCursorColor(bool useForegroundColor, const QColor &color);
0287 
0288     /**
0289      * Returns the color of the keyboard cursor, or an invalid color if the keyboard
0290      * cursor color is set to change according to the foreground color of the character
0291      * underneath it.
0292      */
0293     QColor keyboardCursorColor() const;
0294 
0295     /**
0296      * Returns the number of lines of text which can be displayed in the widget.
0297      *
0298      * This will depend upon the height of the widget and the current font.
0299      * See fontHeight()
0300      */
0301     int lines()
0302     {
0303         return _lines;
0304     }
0305     /**
0306      * Returns the number of characters of text which can be displayed on
0307      * each line in the widget.
0308      *
0309      * This will depend upon the width of the widget and the current font.
0310      * See fontWidth()
0311      */
0312     int columns()
0313     {
0314         return _columns;
0315     }
0316 
0317     /**
0318      * Returns the height of the characters in the font used to draw the text in the display.
0319      */
0320     int fontHeight()
0321     {
0322         return _fontHeight;
0323     }
0324     /**
0325      * Returns the width of the characters in the display.
0326      * This assumes the use of a fixed-width font.
0327      */
0328     int fontWidth()
0329     {
0330         return _fontWidth;
0331     }
0332 
0333     void setSize(int cols, int lins);
0334     void setFixedSize(int cols, int lins);
0335 
0336     // reimplemented
0337     QSize sizeHint() const;
0338 
0339     /**
0340      * Sets which characters, in addition to letters and numbers,
0341      * are regarded as being part of a word for the purposes
0342      * of selecting words in the display by double clicking on them.
0343      *
0344      * The word boundaries occur at the first and last characters which
0345      * are either a letter, number, or a character in @p wc
0346      *
0347      * @param wc An array of characters which are to be considered parts
0348      * of a word ( in addition to letters and numbers ).
0349      */
0350     void setWordCharacters(const QString &wc);
0351     /**
0352      * Returns the characters which are considered part of a word for the
0353      * purpose of selecting words in the display with the mouse.
0354      *
0355      * @see setWordCharacters()
0356      */
0357     QString wordCharacters()
0358     {
0359         return _wordCharacters;
0360     }
0361 
0362     /**
0363      * Sets the type of effect used to alert the user when a 'bell' occurs in the
0364      * terminal session.
0365      *
0366      * The terminal session can trigger the bell effect by calling bell() with
0367      * the alert message.
0368      */
0369     void setBellMode(int mode);
0370     /**
0371      * Returns the type of effect used to alert the user when a 'bell' occurs in
0372      * the terminal session.
0373      *
0374      * See setBellMode()
0375      */
0376     int bellMode()
0377     {
0378         return _bellMode;
0379     }
0380 
0381     /**
0382      * This enum describes the different types of sounds and visual effects which
0383      * can be used to alert the user when a 'bell' occurs in the terminal
0384      * session.
0385      */
0386     enum BellMode {
0387         /** A system beep. */
0388         SystemBeepBell = 0,
0389         /**
0390          * KDE notification.  This may play a sound, show a passive popup
0391          * or perform some other action depending on the user's settings.
0392          */
0393         NotifyBell = 1,
0394         /** A silent, visual bell (eg. inverting the display's colors briefly) */
0395         VisualBell = 2,
0396         /** No bell effects */
0397         NoBell = 3
0398     };
0399 
0400     void setSelection(const QString &t);
0401 
0402     /** Returns the font used to draw characters in the display */
0403     QFont getVTFont()
0404     {
0405         return font();
0406     }
0407 
0408     /**
0409      * Sets the font used to draw the display.  Has no effect if @p font
0410      * is larger than the size of the display itself.
0411      */
0412     void setVTFont(const QFont &font);
0413 
0414     /**
0415      * Specified whether anti-aliasing of text in the terminal display
0416      * is enabled or not.  Defaults to enabled.
0417      */
0418     static void setAntialias(bool antialias)
0419     {
0420         _antialiasText = antialias;
0421     }
0422     /**
0423      * Returns true if anti-aliasing of text in the terminal is enabled.
0424      */
0425     static bool antialias()
0426     {
0427         return _antialiasText;
0428     }
0429 
0430     /**
0431      * Specify whether line chars should be drawn by ourselves or left to
0432      * underlying font rendering libraries.
0433      */
0434     void setDrawLineChars(bool drawLineChars)
0435     {
0436         _drawLineChars = drawLineChars;
0437     }
0438 
0439     /**
0440      * Specifies whether characters with intense colors should be rendered
0441      * as bold. Defaults to true.
0442      */
0443     void setBoldIntense(bool value);
0444     /**
0445      * Returns true if characters with intense colors are rendered in bold.
0446      */
0447     bool getBoldIntense()
0448     {
0449         return _boldIntense;
0450     }
0451 
0452     /**
0453      * Sets whether or not the current height and width of the
0454      * terminal in lines and columns is displayed whilst the widget
0455      * is being resized.
0456      */
0457     void setTerminalSizeHint(bool on)
0458     {
0459         _terminalSizeHint = on;
0460     }
0461     /**
0462      * Returns whether or not the current height and width of
0463      * the terminal in lines and columns is displayed whilst the widget
0464      * is being resized.
0465      */
0466     bool terminalSizeHint()
0467     {
0468         return _terminalSizeHint;
0469     }
0470     /**
0471      * Sets whether the terminal size display is shown briefly
0472      * after the widget is first shown.
0473      *
0474      * See setTerminalSizeHint() , isTerminalSizeHint()
0475      */
0476     void setTerminalSizeStartup(bool on)
0477     {
0478         _terminalSizeStartup = on;
0479     }
0480 
0481     /**
0482      * Sets the status of the BiDi rendering inside the terminal display.
0483      * Defaults to disabled.
0484      */
0485     void setBidiEnabled(bool set)
0486     {
0487         _bidiEnabled = set;
0488     }
0489     /**
0490      * Returns the status of the BiDi rendering in this widget.
0491      */
0492     bool isBidiEnabled()
0493     {
0494         return _bidiEnabled;
0495     }
0496 
0497     /**
0498      * Sets the terminal screen section which is displayed in this widget.
0499      * When updateImage() is called, the display fetches the latest character image from the
0500      * the associated terminal screen window.
0501      *
0502      * In terms of the model-view paradigm, the ScreenWindow is the model which is rendered
0503      * by the TerminalDisplay.
0504      */
0505     void setScreenWindow(ScreenWindow *window);
0506     /** Returns the terminal screen section which is displayed in this widget.  See setScreenWindow() */
0507     ScreenWindow *screenWindow() const;
0508 
0509     static bool HAVE_TRANSPARENCY;
0510 
0511     void setMotionAfterPasting(MotionAfterPasting action);
0512     int motionAfterPasting();
0513     void setConfirmMultilinePaste(bool confirmMultilinePaste);
0514     void setTrimPastedTrailingNewlines(bool trimPastedTrailingNewlines);
0515 
0516     // maps a point on the widget to the position ( ie. line and column )
0517     // of the character at that point.
0518 
0519     CharPos getCharacterPosition(const QPointF &widgetPoint) const;
0520 
0521     void disableBracketedPasteMode(bool disable)
0522     {
0523         _disabledBracketedPasteMode = disable;
0524     }
0525     bool bracketedPasteModeIsDisabled() const
0526     {
0527         return _disabledBracketedPasteMode;
0528     }
0529 
0530 public Q_SLOTS:
0531 
0532     /**
0533      * Causes the terminal display to fetch the latest character image from the associated
0534      * terminal screen ( see setScreenWindow() ) and redraw the display.
0535      */
0536     void updateImage();
0537 
0538     /** Essentially calles processFilters().
0539      */
0540     void updateFilters();
0541 
0542     /**
0543      * Causes the terminal display to fetch the latest line status flags from the
0544      * associated terminal screen ( see setScreenWindow() ).
0545      */
0546     void updateLineProperties();
0547 
0548     /** Copies the selected text to the clipboard. */
0549     void copyClipboard();
0550     /**
0551      * Pastes the content of the clipboard into the
0552      * display.
0553      */
0554     void pasteClipboard();
0555     /**
0556      * Pastes the content of the selection into the
0557      * display.
0558      */
0559     void pasteSelection();
0560 
0561     /**
0562      * Changes whether the flow control warning box should be shown when the flow control
0563      * stop key (Ctrl+S) are pressed.
0564      */
0565     void setFlowControlWarningEnabled(bool enabled);
0566     /**
0567      * Returns true if the flow control warning box is enabled.
0568      * See outputSuspended() and setFlowControlWarningEnabled()
0569      */
0570     bool flowControlWarningEnabled() const
0571     {
0572         return _flowControlWarningEnabled;
0573     }
0574 
0575     /**
0576      * Causes the widget to display or hide a message informing the user that terminal
0577      * output has been suspended (by using the flow control key combination Ctrl+S)
0578      *
0579      * @param suspended True if terminal output has been suspended and the warning message should
0580      *                     be shown or false to indicate that terminal output has been resumed and that
0581      *                     the warning message should disappear.
0582      */
0583     void outputSuspended(bool suspended);
0584 
0585     /**
0586      * Sets whether the program whoose output is being displayed in the view
0587      * is interested in mouse events.
0588      *
0589      * If this is set to true, mouse signals will be emitted by the view when the user clicks, drags
0590      * or otherwise moves the mouse inside the view.
0591      * The user interaction needed to create selections will also change, and the user will be required
0592      * to hold down the shift key to create a selection or perform other mouse activities inside the
0593      * view area - since the program running in the terminal is being allowed to handle normal mouse
0594      * events itself.
0595      *
0596      * @param usesMouse Set to true if the program running in the terminal is interested in mouse events
0597      * or false otherwise.
0598      */
0599     void setUsesMouse(bool usesMouse);
0600 
0601     /** See setUsesMouse() */
0602     bool usesMouse() const;
0603 
0604     void setBracketedPasteMode(bool bracketedPasteMode);
0605     bool bracketedPasteMode() const;
0606 
0607     /**
0608      * Shows a notification that a bell event has occurred in the terminal.
0609      * TODO: More documentation here
0610      */
0611     void bell(const QString &message);
0612 
0613     /**
0614      * Sets the background of the display to the specified color.
0615      * @see setColorTable(), setForegroundColor()
0616      */
0617     void setBackgroundColor(const QColor &color);
0618 
0619     /**
0620      * Sets the text of the display to the specified color.
0621      * @see setColorTable(), setBackgroundColor()
0622      */
0623     void setForegroundColor(const QColor &color);
0624 
0625     void selectionChanged();
0626 
0627     // QMLTermWidget
0628     void setColorScheme(const QString &name);
0629     QString colorScheme() const;
0630     QStringList availableColorSchemes();
0631 
0632     void simulateKeyPress(int key, int modifiers, bool pressed, quint32 nativeScanCode, const QString &text);
0633     void simulateKeySequence(const QKeySequence &sequence);
0634     void simulateWheel(int x, int y, int buttons, int modifiers, QPoint angleDelta);
0635     void simulateMouseMove(int x, int y, int button, int buttons, int modifiers);
0636     void simulateMousePress(int x, int y, int button, int buttons, int modifiers);
0637     void simulateMouseRelease(int x, int y, int button, int buttons, int modifiers);
0638     void simulateMouseDoubleClick(int x, int y, int button, int buttons, int modifiers);
0639 
0640 Q_SIGNALS:
0641 
0642     /**
0643      * Emitted when the user presses a key whilst the terminal widget has focus.
0644      */
0645     void keyPressedSignal(QKeyEvent *e, bool fromPaste);
0646 
0647     /**
0648      * A mouse event occurred.
0649      * @param button The mouse button (0 for left button, 1 for middle button, 2 for right button, 3 for release)
0650      * @param column The character column where the event occurred
0651      * @param line The character row where the event occurred
0652      * @param eventType The type of event.  0 for a mouse press / release or 1 for mouse motion
0653      */
0654     void mouseSignal(int button, int column, int line, int eventType);
0655     void changedFontMetricSignal(qreal height, qreal width);
0656     void changedContentSizeSignal(int height, int width);
0657 
0658     /**
0659      * Emitted when the user right clicks on the display, or right-clicks with the Shift
0660      * key held down if usesMouse() is true.
0661      *
0662      * This can be used to display a context menu.
0663      */
0664     void configureRequest(const QPoint &position);
0665 
0666     /**
0667      * When a shortcut which is also a valid terminal key sequence is pressed while
0668      * the terminal widget  has focus, this signal is emitted to allow the host to decide
0669      * whether the shortcut should be overridden.
0670      * When the shortcut is overridden, the key sequence will be sent to the terminal emulation instead
0671      * and the action associated with the shortcut will not be triggered.
0672      *
0673      * @p override is set to false by default and the shortcut will be triggered as normal.
0674      */
0675     void overrideShortcutCheck(QKeyEvent *keyEvent, bool &override);
0676 
0677     void isBusySelecting(bool busy);
0678     void sendStringToEmu(const char *);
0679 
0680     // qtermwidget signals
0681     void copyAvailable(bool available);
0682     void termGetFocus();
0683     void termLostFocus();
0684 
0685     void notifyBell(const QString &bell);
0686     void usesMouseChanged();
0687 
0688     // QMLTermWidget
0689     void sessionChanged();
0690     void sizeChanged();
0691     void imagePainted();
0692     void scrollbarValueChanged();
0693     void scrollbarParamsChanged(int value);
0694     void vtFontChanged();
0695     void lineSpacingChanged();
0696     void availableColorSchemesChanged();
0697     void colorSchemeChanged();
0698     void fullCursorHeightChanged();
0699     void blinkingCursorStateChanged();
0700     void boldIntenseChanged();
0701 
0702 protected:
0703     bool event(QEvent *) override;
0704 
0705     void showEvent(QShowEvent *);
0706     void hideEvent(QHideEvent *);
0707     void resizeEvent(QResizeEvent *);
0708 
0709     virtual void fontChange(const QFont &font);
0710     void focusInEvent(QFocusEvent *event) override;
0711     void focusOutEvent(QFocusEvent *event) override;
0712     void keyPressEvent(QKeyEvent *event) override;
0713     void mouseDoubleClickEvent(QMouseEvent *ev) override;
0714     void mousePressEvent(QMouseEvent *) override;
0715     void mouseReleaseEvent(QMouseEvent *) override;
0716     void mouseMoveEvent(QMouseEvent *) override;
0717     virtual void extendSelection(const QPoint &pos);
0718     void wheelEvent(QWheelEvent *) override;
0719 
0720     bool focusNextPrevChild(bool next);
0721 
0722     // drag and drop
0723     void dragEnterEvent(QDragEnterEvent *event) override;
0724     void dropEvent(QDropEvent *event) override;
0725     void doDrag();
0726     enum DragState { diNone, diPending, diDragging };
0727 
0728     struct _dragInfo {
0729         DragState state;
0730         QPoint start;
0731         QDrag *dragObject;
0732     } dragInfo;
0733 
0734     // classifies the 'ch' into one of three categories
0735     // and returns a character to indicate which category it is in
0736     //
0737     //     - A space (returns ' ')
0738     //     - Part of a word (returns 'a')
0739     //     - Other characters (returns the input character)
0740     QChar charClass(QChar ch) const;
0741 
0742     void clearImage();
0743 
0744     void mouseTripleClickEvent(QMouseEvent *ev);
0745 
0746     // reimplemented
0747     void inputMethodEvent(QInputMethodEvent *event) override;
0748     QVariant inputMethodQuery(Qt::InputMethodQuery query) const override;
0749 
0750     // QMLTermWidget
0751     void paint(QPainter *painter) override;
0752 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
0753     void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override;
0754 #else
0755     void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override;
0756 #endif
0757     void inputMethodQuery(QInputMethodQueryEvent *event);
0758     void itemChange(ItemChange change, const ItemChangeData &value) override;
0759 
0760     constexpr int loc(int x, int y) const
0761     {
0762         return y * _columns + x;
0763     }
0764 
0765 protected Q_SLOTS:
0766 
0767     void scrollBarPositionChanged(int value);
0768     void blinkEvent();
0769     void blinkCursorEvent();
0770 
0771     // Renables bell noises and visuals.  Used to disable further bells for a short period of time
0772     // after emitting the first in a sequence of bell events.
0773     void enableBell();
0774 
0775 private Q_SLOTS:
0776 
0777     void swapColorTable();
0778     void tripleClickTimeout(); // resets possibleTripleClick
0779 
0780 private:
0781     // -- Drawing helpers --
0782 
0783     // determine the width of this text
0784     int textWidth(int startColumn, int length, int line) const;
0785     // determine the area that encloses this series of characters
0786     QRect calculateTextArea(int topLeftX, int topLeftY, int startColumn, int line, int length);
0787 
0788     // divides the part of the display specified by 'rect' into
0789     // fragments according to their colors and styles and calls
0790     // drawTextFragment() to draw the fragments
0791     void drawContents(QPainter &paint, const QRect &rect);
0792     // draws a section of text, all the text in this section
0793     // has a common color and style
0794     void drawTextFragment(QPainter &painter, const QRect &rect, const QString &text, const Character *style);
0795     // draws the background for a text fragment
0796     // if useOpacitySetting is true then the color's alpha value will be set to
0797     // the display's transparency (set with setOpacity()), otherwise the background
0798     // will be drawn fully opaque
0799     void drawBackground(QPainter &painter, const QRect &rect, const QColor &color, bool useOpacitySetting);
0800     // draws the cursor character
0801     void drawCursor(QPainter &painter, const QRect &rect, const QColor &foregroundColor, const QColor &backgroundColor, bool &invertColors);
0802     // draws the characters or line graphics in a text fragment
0803     void drawCharacters(QPainter &painter, const QRect &rect, const QString &text, const Character *style, bool invertCharacterColor);
0804     // draws a string of line graphics
0805     void drawLineCharString(QPainter &painter, int x, int y, QStringView str, const Character *attributes) const;
0806 
0807     // draws the preedit string for input methods
0808     void drawInputMethodPreeditString(QPainter &painter, const QRect &rect);
0809 
0810     // --
0811 
0812     // maps an area in the character image to an area on the widget
0813     QRect imageToWidget(const QRect &imageArea) const;
0814 
0815     // the area where the preedit string for input methods will be draw
0816     QRect preeditRect() const;
0817 
0818     // shows a notification window in the middle of the widget indicating the terminal's
0819     // current size in columns and lines
0820     void showResizeNotification();
0821 
0822     // scrolls the image by a number of lines.
0823     // 'lines' may be positive ( to scroll the image down )
0824     // or negative ( to scroll the image up )
0825     // 'region' is the part of the image to scroll - currently only
0826     // the top, bottom and height of 'region' are taken into account,
0827     // the left and right are ignored.
0828     void scrollImage(int lines, const QRect &region);
0829 
0830     void calcGeometry();
0831     void propagateSize();
0832     void updateImageSize();
0833     void makeImage();
0834 
0835     void paintFilters(QPainter &painter);
0836 
0837     // returns a region covering all of the areas of the widget which contain
0838     // a hotspot
0839     QRegion hotSpotRegion() const;
0840 
0841     // returns the position of the cursor in columns and lines
0842     QPoint cursorPosition() const;
0843 
0844     // redraws the cursor
0845     void updateCursor();
0846 
0847     bool handleShortcutOverrideEvent(QKeyEvent *event);
0848 
0849     constexpr bool isLineChar(QChar c) const;
0850     constexpr bool isLineCharString(QStringView string) const;
0851 
0852     // the window onto the terminal screen which this display
0853     // is currently showing.
0854     QPointer<ScreenWindow> _screenWindow;
0855 
0856     bool _allowBell;
0857 
0858     QGridLayout *_gridLayout;
0859 
0860     bool _fixedFont; // has fixed pitch
0861     qreal _fontHeight; // height
0862     qreal _fontWidth; // width
0863     int _fontAscent; // ascend
0864     bool _boldIntense; // Whether intense colors should be rendered with bold font
0865 
0866     int _leftMargin; // offset
0867     int _topMargin; // offset
0868 
0869     int _lines; // the number of lines that can be displayed in the widget
0870     int _columns; // the number of columns that can be displayed in the widget
0871 
0872     int _usedLines; // the number of lines that are actually being used, this will be less
0873                     // than 'lines' if the character image provided with setImage() is smaller
0874                     // than the maximum image size which can be displayed
0875 
0876     int _usedColumns; // the number of columns that are actually being used, this will be less
0877                       // than 'columns' if the character image provided with setImage() is smaller
0878                       // than the maximum image size which can be displayed
0879 
0880     int _contentHeight;
0881     int _contentWidth;
0882     std::vector<Character> _image; // [lines][columns]
0883                                    // only the area [usedLines][usedColumns] in the image contains valid data
0884 
0885     int _imageSize;
0886     QVector<LineProperty> _lineProperties;
0887 
0888     std::array<ColorEntry, TABLE_COLORS> _colorTable;
0889     uint _randomSeed;
0890 
0891     bool _resizing;
0892     bool _terminalSizeHint;
0893     bool _terminalSizeStartup;
0894     bool _bidiEnabled;
0895     bool _mouseMarks;
0896     bool _bracketedPasteMode;
0897     bool _disabledBracketedPasteMode;
0898 
0899     QPoint _iPntSel; // initial selection point
0900     QPoint _pntSel; // current selection point
0901     QPoint _tripleSelBegin; // help avoid flicker
0902     int _actSel; // selection state
0903     bool _wordSelectionMode;
0904     bool _lineSelectionMode;
0905     bool _preserveLineBreaks;
0906     bool _columnSelectionMode;
0907 
0908     QClipboard *_clipboard;
0909     QScrollBar *_scrollBar;
0910     QTermWidget::ScrollBarPosition _scrollbarLocation;
0911     QString _wordCharacters;
0912     int _bellMode;
0913 
0914     bool _blinking; // hide text in paintEvent
0915     bool _hasBlinker; // has characters to blink
0916     bool _cursorBlinking; // hide cursor in paintEvent
0917     bool _hasBlinkingCursor; // has blinking cursor enabled
0918     bool _allowBlinkingText; // allow text to blink
0919     bool _ctrlDrag; // require Ctrl key for drag
0920     TripleClickMode _tripleClickMode;
0921     bool _isFixedSize; // Columns / lines are locked.
0922     QTimer *_blinkTimer; // active when hasBlinker
0923     QTimer *_blinkCursorTimer; // active when hasBlinkingCursor
0924 
0925     // QMenu* _drop;
0926     QString _dropText;
0927     int _dndFileCount;
0928 
0929     bool _possibleTripleClick; // is set in mouseDoubleClickEvent and deleted
0930                                // after QApplication::doubleClickInterval() delay
0931 
0932     QLabel *_resizeWidget;
0933     QTimer *_resizeTimer;
0934 
0935     bool _flowControlWarningEnabled;
0936 
0937     // widgets related to the warning message that appears when the user presses Ctrl+S to suspend
0938     // terminal output - informing them what has happened and how to resume output
0939     QLabel *_outputSuspendedLabel;
0940 
0941     uint _lineSpacing;
0942     QString _colorScheme;
0943     bool _colorsInverted; // true during visual bell
0944 
0945     QSize _size;
0946 
0947     qreal _opacity;
0948 
0949     // list of filters currently applied to the display.  used for links and
0950     // search highlight
0951     std::unique_ptr<TerminalImageFilterChain> _filterChain;
0952     QRegion _mouseOverHotspotArea;
0953 
0954     Emulation::KeyboardCursorShape _cursorShape;
0955 
0956     // custom cursor color.  if this is invalid then the foreground
0957     // color of the character under the cursor is used
0958     QColor _cursorColor;
0959 
0960     MotionAfterPasting mMotionAfterPasting;
0961     bool _confirmMultilinePaste;
0962     bool _trimPastedTrailingNewlines;
0963 
0964     struct InputMethodData {
0965         QString preeditString;
0966         QRect previousPreeditRect;
0967     };
0968     InputMethodData _inputMethodData;
0969 
0970     static bool _antialiasText; // do we antialias or not
0971 
0972     // the delay in milliseconds between redrawing blinking text
0973     static const int TEXT_BLINK_DELAY = 500;
0974 
0975     int _leftBaseMargin;
0976     int _topBaseMargin;
0977 
0978     // QMLTermWidget port functions
0979     QFont m_font;
0980     QPalette m_palette;
0981     QPalette::ColorRole m_color_role;
0982     TerminalSession *m_session = nullptr;
0983     bool m_full_cursor_height;
0984 
0985     QFont font() const
0986     {
0987         return m_font;
0988     }
0989 
0990     const QPalette palette()
0991     {
0992         return m_palette;
0993     }
0994     void setPalette(const QPalette &p)
0995     {
0996         m_palette = p;
0997     }
0998 
0999     QPalette::ColorRole backgroundRole()
1000     {
1001         return m_color_role;
1002     }
1003     void setBackgroundRole(QPalette::ColorRole role)
1004     {
1005         m_color_role = role;
1006     }
1007 
1008     void update(const QRegion &region);
1009     void update();
1010 
1011     QRect contentsRect() const;
1012     QSize size() const;
1013 
1014     void setSession(TerminalSession *session);
1015     TerminalSession *getSession();
1016 
1017     QSize getTerminalSize();
1018 
1019     bool getUsesMouse();
1020 
1021     int getScrollbarValue();
1022     int getScrollbarMaximum();
1023     int getScrollbarMinimum();
1024 
1025     QSize getFontMetrics();
1026 
1027     void setFullCursorHeight(bool val);
1028 
1029     bool _drawLineChars;
1030 
1031 public:
1032     bool fullCursorHeight() const;
1033 };
1034 
1035 }
1036 
1037 #endif // TERMINALDISPLAY_H