TerminalDisplay.h 30.4 KB
Newer Older
1
/*
2
3
    Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
    Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301  USA.
*/
20

21
22
#ifndef TERMINALDISPLAY_H
#define TERMINALDISPLAY_H
23

24
// Qt
25
26
#include <QColor>
#include <QPointer>
27
#include <QWidget>
28

29
// Konsole
30
#include "Character.h"
Laurent Montel's avatar
Laurent Montel committed
31
#include "konsoleprivate_export.h"
32
#include "ScreenWindow.h"
33
#include "colorscheme/ColorScheme.h"
34
#include "Enumeration.h"
35
#include "ScrollState.h"
36
#include "TerminalHeaderBar.h"
37

38
39
40
class QDrag;
class QDragEnterEvent;
class QDropEvent;
Laurent Montel's avatar
Laurent Montel committed
41
42
class QLabel;
class QTimer;
43
class QEvent;
44
class QVBoxLayout;
45
46
class QKeyEvent;
class QScrollBar;
47
48
class QShowEvent;
class QHideEvent;
49
class QTimerEvent;
50
51
class KMessageWidget;

Kurt Hindenburg's avatar
Kurt Hindenburg committed
52
namespace Konsole {
53
54
55
class FilterChain;
class TerminalImageFilterChain;
class SessionController;
56
class IncrementalSearchBar;
57
class HotSpot;
58
class Profile;
59

60
61
62
63
/**
 * A widget which displays output from a terminal emulation and sends input keypresses and mouse activity
 * to the terminal.
 *
Jekyll Wu's avatar
Jekyll Wu committed
64
 * When the terminal emulation receives new output from the program running in the terminal,
65
66
67
 * it will update the display by calling updateImage().
 *
 * TODO More documentation
68
 */
69
class KONSOLEPRIVATE_EXPORT TerminalDisplay : public QWidget
70
{
Kurt Hindenburg's avatar
Kurt Hindenburg committed
71
    Q_OBJECT
72
73

public:
74
    /** Constructs a new terminal display widget with the specified parent. */
Kurt Hindenburg's avatar
Kurt Hindenburg committed
75
    explicit TerminalDisplay(QWidget *parent = nullptr);
76
    ~TerminalDisplay() override;
77

Kurt Hindenburg's avatar
Kurt Hindenburg committed
78
    void showDragTarget(const QPoint& cursorPos);
79
80
    void hideDragTarget();

81
    void applyProfile(const QExplicitlySharedDataPointer<Profile>& profile);
82

83
    /** Returns the terminal color palette used by the display. */
Kurt Hindenburg's avatar
Kurt Hindenburg committed
84
    const ColorEntry *colorTable() const;
85
86
    /** Sets the terminal color palette used by the display. */
    void setColorTable(const ColorEntry table[]);
Constantin Berzan's avatar
APIDOX    
Constantin Berzan committed
87
88
89
90
    /**
     * Sets the seed used to generate random colors for the display
     * (in color schemes that support them).
     */
91
    void setRandomSeed(uint randomSeed);
Constantin Berzan's avatar
APIDOX    
Constantin Berzan committed
92
93
94
95
    /**
     * Returns the seed used to generate random colors for the display
     * (in color schemes that support them).
     */
96
97
    uint randomSeed() const;

98
99
    /** Sets the opacity of the terminal display. */
    void setOpacity(qreal opacity);
100

101
    /** Sets the background picture */
102
    void setWallpaper(const ColorSchemeWallpaper::Ptr &p);
103

Jekyll Wu's avatar
Jekyll Wu committed
104
    /**
105
106
107
     * Specifies whether the terminal display has a vertical scroll bar, and if so whether it
     * is shown on the left or right side of the display.
     */
108
    void setScrollBarPosition(Enum::ScrollBarPositionEnum position);
109

Jekyll Wu's avatar
Jekyll Wu committed
110
    /**
111
112
113
     * Sets the current position and range of the display's scroll bar.
     *
     * @param cursor The position of the scroll bar's thumb.
114
     * @param slines The maximum value of the scroll bar.
115
     */
116
    void setScroll(int cursor, int slines);
117

118
119
    void setScrollFullPage(bool fullPage);
    bool scrollFullPage() const;
120
121
    void setHighlightScrolledLines(bool highlight);

122
    /**
123
124
125
126
127
128
129
130
131
132
     * Returns the display's filter chain.  When the image for the display is updated,
     * the text is passed through each filter in the chain.  Each filter can define
     * hotspots which correspond to certain strings (such as URLs or particular words).
     * Depending on the type of the hotspots created by the filter ( returned by Filter::Hotspot::type() )
     * the view will draw visual cues such as underlines on mouse-over for links or translucent
     * rectangles for markers.
     *
     * To add a new filter to the view, call:
     *      viewWidget->filterChain()->addFilter( filterObject );
     */
Kurt Hindenburg's avatar
Kurt Hindenburg committed
133
    FilterChain *filterChain() const;
134

Jekyll Wu's avatar
Jekyll Wu committed
135
    /**
136
137
     * Updates the filters in the display's filter chain.  This will cause
     * the hotspots to be updated to match the current image.
138
     *
Jekyll Wu's avatar
Jekyll Wu committed
139
     * WARNING:  This function can be expensive depending on the
140
     * image size and number of filters in the filterChain()
141
     *
142
143
144
145
146
147
     * TODO - This API does not really allow efficient usage.  Revise it so
     * that the processing can be done in a better way.
     *
     * eg:
     *      - Area of interest may be known ( eg. mouse cursor hovering
     *      over an area )
Jekyll Wu's avatar
Jekyll Wu committed
148
     */
149
    void processFilters();
150

Jekyll Wu's avatar
Jekyll Wu committed
151
    /**
152
153
154
     * Returns a list of menu actions created by the filters for the content
     * at the given @p position.
     */
155
    QSharedPointer<HotSpot> filterActions(const QPoint &position);
156

Jekyll Wu's avatar
Jekyll Wu committed
157
158
    /** Specifies whether or not the cursor can blink. */
    void setBlinkingCursorEnabled(bool blink);
159

160
161
162
    /** Specifies whether or not text can blink. */
    void setBlinkingTextEnabled(bool blink);

163
164
165
    void setLineSpacing(uint);
    uint lineSpacing() const;

Kurt Hindenburg's avatar
Kurt Hindenburg committed
166
167
    void setSessionController(SessionController *controller);
    SessionController *sessionController();
168

Jekyll Wu's avatar
Jekyll Wu committed
169
170
    /**
     * Sets the shape of the keyboard cursor.  This is the cursor drawn
171
172
     * at the position in the terminal where keyboard input will appear.
     *
Jekyll Wu's avatar
Jekyll Wu committed
173
     * In addition the terminal display widget also has a cursor for
174
175
176
177
178
     * the mouse pointer, which can be set using the QWidget::setCursor()
     * method.
     *
     * Defaults to BlockCursor
     */
179
    void setKeyboardCursorShape(Enum::CursorShapeEnum shape);
180

181
182
183
184
185
186
187
188
189
190
191
192
    /**
     * Sets the Cursor Style (DECSCUSR) via escape sequences
     * @p shape cursor shape
     * @p isBlinking if true, the cursor will be set to blink
    */
    void setCursorStyle(Enum::CursorShapeEnum shape, bool isBlinking);
    /**
     * Resets the cursor style to the current profile cursor shape and
     * blinking settings
    */
    void resetCursorStyle();

193
    /**
Jekyll Wu's avatar
Jekyll Wu committed
194
     * Sets the color used to draw the keyboard cursor.
195
196
197
198
     *
     * The keyboard cursor defaults to using the foreground color of the character
     * underneath it.
     *
199
200
201
202
203
204
     * @param color By default, the widget uses the color of the
     * character under the cursor to draw the cursor, and inverts the
     * color of that character to make sure it is still readable. If @p
     * color is a valid QColor, the widget uses that color to draw the
     * cursor. If @p color is not an valid QColor, the widget falls back
     * to the default behavior.
205
     */
Kurt Hindenburg's avatar
Kurt Hindenburg committed
206
    void setKeyboardCursorColor(const QColor &color);
207

208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
    /**
     * Sets the color used to draw the character underneath the keyboard cursor.
     *
     * The keyboard cursor defaults to using the background color of the
     * terminal cell to draw the character at the cursor position.
     *
     * @param color By default, the widget uses the color of the
     * character under the cursor to draw the cursor, and inverts the
     * color of that character to make sure it is still readable. If @p
     * color is a valid QColor, the widget uses that color to draw the
     * character underneath the cursor. If @p color is not an valid QColor,
     * the widget falls back to the default behavior.
     */
    void setKeyboardCursorTextColor(const QColor &color);

223
224
225
226
227
228
    /**
     * Returns the number of lines of text which can be displayed in the widget.
     *
     * This will depend upon the height of the widget and the current font.
     * See fontHeight()
     */
Kurt Hindenburg's avatar
Kurt Hindenburg committed
229
230
    int  lines() const
    {
Kurt Hindenburg's avatar
Kurt Hindenburg committed
231
232
        return _lines;
    }
Kurt Hindenburg's avatar
Kurt Hindenburg committed
233

234
235
236
237
238
239
240
    /**
     * Returns the number of characters of text which can be displayed on
     * each line in the widget.
     *
     * This will depend upon the width of the widget and the current font.
     * See fontWidth()
     */
Kurt Hindenburg's avatar
Kurt Hindenburg committed
241
242
    int  columns() const
    {
Kurt Hindenburg's avatar
Kurt Hindenburg committed
243
244
        return _columns;
    }
245

246
247
248
    /**
     * Returns the height of the characters in the font used to draw the text in the display.
     */
Kurt Hindenburg's avatar
Kurt Hindenburg committed
249
250
    int  fontHeight() const
    {
Kurt Hindenburg's avatar
Kurt Hindenburg committed
251
252
        return _fontHeight;
    }
Kurt Hindenburg's avatar
Kurt Hindenburg committed
253

254
    /**
Jekyll Wu's avatar
Jekyll Wu committed
255
     * Returns the width of the characters in the display.
256
257
     * This assumes the use of a fixed-width font.
     */
Kurt Hindenburg's avatar
Kurt Hindenburg committed
258
259
    int  fontWidth() const
    {
Kurt Hindenburg's avatar
Kurt Hindenburg committed
260
261
        return _fontWidth;
    }
262

263
264
    void setSize(int columns, int lines);

265
    // reimplemented
266
    QSize sizeHint() const override;
267

268
    /**
Jekyll Wu's avatar
Jekyll Wu committed
269
     * Sets which characters, in addition to letters and numbers,
270
271
272
273
274
275
276
277
278
     * are regarded as being part of a word for the purposes
     * of selecting words in the display by double clicking on them.
     *
     * The word boundaries occur at the first and last characters which
     * are either a letter, number, or a character in @p wc
     *
     * @param wc An array of characters which are to be considered parts
     * of a word ( in addition to letters and numbers ).
     */
Kurt Hindenburg's avatar
Kurt Hindenburg committed
279
    void setWordCharacters(const QString &wc);
280

Jekyll Wu's avatar
Jekyll Wu committed
281
282
    /**
     * Sets the type of effect used to alert the user when a 'bell' occurs in the
283
284
285
286
287
     * terminal session.
     *
     * The terminal session can trigger the bell effect by calling bell() with
     * the alert message.
     */
288
    void setBellMode(int mode);
Jekyll Wu's avatar
Jekyll Wu committed
289
    /**
290
291
     * Returns the type of effect used to alert the user when a 'bell' occurs in
     * the terminal session.
Kurt Hindenburg's avatar
Kurt Hindenburg committed
292
     *
293
294
     * See setBellMode()
     */
295
296
    int bellMode() const;

297
298
299
    /** Play a visual bell for prompt or warning. */
    void visualBell();

300
    /** Returns the font used to draw characters in the display */
Kurt Hindenburg's avatar
Kurt Hindenburg committed
301
302
    QFont getVTFont()
    {
Kurt Hindenburg's avatar
Kurt Hindenburg committed
303
304
        return font();
    }
305

306
307
308
309
    TerminalHeaderBar *headerBar() const
    {
        return _headerBar;
    }
Jekyll Wu's avatar
Jekyll Wu committed
310
    /**
311
     * Sets the font used to draw the display.  Has no effect if @p font
Jekyll Wu's avatar
Jekyll Wu committed
312
     * is larger than the size of the display itself.
313
     */
314
    void setVTFont(const QFont &f);
315

316
317
318
319
320
321
    /** Increases the font size */
    void increaseFontSize();

    /** Decreases the font size */
    void decreaseFontSize();

Lukas Bergdoll's avatar
Lukas Bergdoll committed
322
323
324
    /** Reset the font size */
    void resetFontSize();

325
326
327
    QRect contentRect() const { return _contentRect; }
    bool openLinksByDirectClick() const { return _openLinksByDirectClick; }

328
329
330
331
332
333
334
335
    /**
     * Sets the terminal screen section which is displayed in this widget.
     * When updateImage() is called, the display fetches the latest character image from the
     * the associated terminal screen window.
     *
     * In terms of the model-view paradigm, the ScreenWindow is the model which is rendered
     * by the TerminalDisplay.
     */
Kurt Hindenburg's avatar
Kurt Hindenburg committed
336
    void setScreenWindow(ScreenWindow *window);
337
    /** Returns the terminal screen section which is displayed in this widget.  See setScreenWindow() */
Kurt Hindenburg's avatar
Kurt Hindenburg committed
338
    ScreenWindow *screenWindow() const;
339

340
341
342
    // Select the current line.
    void selectCurrentLine();

343
344
345
346
    /**
     * Selects everything in the terminal
     */
    void selectAll();
347
348
    
    // TODO: Move this code to KonsolePrintManager
Kurt Hindenburg's avatar
Kurt Hindenburg committed
349
    void printContent(QPainter &painter, bool friendly);
350

351
352
353
354
355
356
    /**
     * Gets the foreground of the display
     * @see setForegroundColor(), setColorTable(), setBackgroundColor()
     */
    QColor getForegroundColor() const;

357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
    /**
     * Gets the background of the display
     * @see setBackgroundColor(), setColorTable(), setForegroundColor()
     */
    QColor getBackgroundColor() const;

    bool bracketedPasteMode() const;

    /**
     * Returns true if the flow control warning box is enabled.
     * See outputSuspended() and setFlowControlWarningEnabled()
     */
    bool flowControlWarningEnabled() const
    {
        return _flowControlWarningEnabled;
    }

374
375
    /** See setUsesMouseTracking() */
    bool usesMouseTracking() const;
376

377
378
379
    /** See setAlternateScrolling() */
    bool alternateScrolling() const;

380
381
382
383
384
    bool hasCompositeFocus() const
    {
        return _hasCompositeFocus;
    }

385
386
387
388
    // maps an area in the character image to an area on the widget
    QRect imageToWidget(const QRect &imageArea) const;
    QRect widgetToImage(const QRect &widgetArea) const;

389
390
391
392
393
    // maps a point on the widget to the position ( ie. line and column )
    // of the character at that point. When the edge is true, it maps to
    // a character which left edge is closest to the point.
    void getCharacterPosition(const QPoint &widgetPoint, int &line, int &column, bool edge) const;

394
public Q_SLOTS:
395
396
397
398
399
    /**
     * Scrolls current ScreenWindow
     *
     * it's needed for proper handling scroll commands in the Vt102Emulation class
     */
Kurt Hindenburg's avatar
Kurt Hindenburg committed
400
    void scrollScreenWindow(enum ScreenWindow::RelativeScrollMode mode, int amount);
401

Jekyll Wu's avatar
Jekyll Wu committed
402
    /**
403
404
405
     * Causes the terminal display to fetch the latest character image from the associated
     * terminal screen ( see setScreenWindow() ) and redraw the display.
     */
Kurt Hindenburg's avatar
Kurt Hindenburg committed
406
    void updateImage();
407
    /**
Jekyll Wu's avatar
Jekyll Wu committed
408
409
410
     * Causes the terminal display to fetch the latest line status flags from the
     * associated terminal screen ( see setScreenWindow() ).
     */
411
    void updateLineProperties();
412

413
414
    void setAutoCopySelectedText(bool enabled);

415
416
    void setCopyTextAsHTML(bool enabled);

417
418
419
420
421
422
    void setMiddleClickPasteMode(Enum::MiddleClickPasteModeEnum mode);

    /** Copies the selected text to the X11 Selection. */
    void copyToX11Selection();

    /** Copies the selected text to the system clipboard. */
Jekyll Wu's avatar
Jekyll Wu committed
423
    void copyToClipboard();
424

Jekyll Wu's avatar
Jekyll Wu committed
425
    /**
426
427
428
429
430
     * Pastes the content of the clipboard into the display.
     *
     * URLs of local files are treated specially:
     *  - The scheme part, "file://", is removed from each URL
     *  - The URLs are pasted as a space-separated list of file paths
431
     */
432
    void pasteFromClipboard(bool appendEnter = false);
433
    /**
434
     * Pastes the content of the X11 selection into the
435
436
     * display.
     */
437
    void pasteFromX11Selection(bool appendEnter = false);
Robert Knight's avatar
   
Robert Knight committed
438

Jekyll Wu's avatar
Jekyll Wu committed
439
    /**
440
441
442
       * Changes whether the flow control warning box should be shown when the flow control
       * stop key (Ctrl+S) are pressed.
       */
443
    void setFlowControlWarningEnabled(bool enable);
Jekyll Wu's avatar
Jekyll Wu committed
444
    /**
445
446
447
448
449
450
     * Causes the widget to display or hide a message informing the user that terminal
     * output has been suspended (by using the flow control key combination Ctrl+S)
     *
     * @param suspended True if terminal output has been suspended and the warning message should
     *                     be shown or false to indicate that terminal output has been resumed and that
     *                     the warning message should disappear.
Jekyll Wu's avatar
Jekyll Wu committed
451
     */
452
    void outputSuspended(bool suspended);
453

Robert Knight's avatar
   
Robert Knight committed
454
    /**
455
456
     * Sets whether the program currently running in the terminal is interested
     * in Mouse Tracking events.
Robert Knight's avatar
   
Robert Knight committed
457
     *
458
     * When set to true, Konsole will send Mouse Tracking events.
Robert Knight's avatar
   
Robert Knight committed
459
     *
460
461
462
463
464
465
466
467
     * The user interaction needed to create text selections will change
     * also, and the user will be required to hold down the Shift key to
     * create a selection or perform other mouse activities inside the view
     * area, since the program running in the terminal is being allowed
     * to handle normal mouse events itself.
     *
     * @param on Set to true if the program running in the terminal is
     * interested in Mouse Tracking events or false otherwise.
Robert Knight's avatar
   
Robert Knight committed
468
     */
469
    void setUsesMouseTracking(bool on);
470

471
472
473
474
475
476
477
478
479
    /**
     * Sets the AlternateScrolling profile property which controls whether
     * to emulate up/down key presses for mouse scroll wheel events.
     * For more details, check the documentation of that property in the
     * Profile header.
     * Enabled by default.
     */
    void setAlternateScrolling(bool enable);

480
    void setBracketedPasteMode(bool on);
481

482
483
484
485
    /**
     * Shows a notification that a bell event has occurred in the terminal.
     * TODO: More documentation here
     */
Kurt Hindenburg's avatar
Kurt Hindenburg committed
486
    void bell(const QString &message);
487

Jekyll Wu's avatar
Jekyll Wu committed
488
489
    /**
     * Sets the background of the display to the specified color.
490
     * @see setColorTable(), getBackgroundColor(), setForegroundColor()
491
     */
Kurt Hindenburg's avatar
Kurt Hindenburg committed
492
    void setBackgroundColor(const QColor &color);
493

Jekyll Wu's avatar
Jekyll Wu committed
494
495
    /**
     * Sets the text of the display to the specified color.
496
     * @see setColorTable(), setBackgroundColor(), getBackgroundColor()
497
     */
Kurt Hindenburg's avatar
Kurt Hindenburg committed
498
    void setForegroundColor(const QColor &color);
499

500
501
502
503
504
505
506
507
508
509
    /**
     * Sets the display's contents margins.
     */
    void setMargin(int margin);

    /**
     * Sets whether the contents are centered between the margins.
     */
    void setCenterContents(bool enable);

510
    /**
511
     * Return the current color scheme
512
     */
513
514
515
516
517
518
519
520
    ColorScheme const *colorScheme() const
    {
        return _colorScheme;
    }

    Enum::ScrollBarPositionEnum scrollBarPosition() const
    {
        return _scrollbarLocation;
521
522
    }

523
524
525
526
    Qt::Edge droppedEdge() const {
        return _overlayEdge;
    }

527
528
    // Used to show/hide the message widget
    void updateReadOnlyState(bool readonly);
529
    IncrementalSearchBar *searchBar() const;
530
531
532

    // Used for requestPrint
    void printScreen();
533
    Character getCursorCharacter(int column, int line);
534

535
Q_SIGNALS:
536
    void requestToggleExpansion();
537
538
539
    /**
     * Emitted when the user presses a key whilst the terminal widget has focus.
     */
Kurt Hindenburg's avatar
Kurt Hindenburg committed
540
    void keyPressedSignal(QKeyEvent *event);
541

Jekyll Wu's avatar
Jekyll Wu committed
542
    /**
543
     * A mouse event occurred.
544
545
546
     * @param button The mouse button (0 for left button, 1 for middle button, 2 for right button, 3 for release)
     * @param column The character column where the event occurred
     * @param line The character row where the event occurred
547
548
     * @param eventType The type of event.  0 for a mouse press / release or 1 for mouse motion
     */
549
    void mouseSignal(int button, int column, int line, int eventType);
550
551
    void changedFontMetricSignal(int height, int width);
    void changedContentSizeSignal(int height, int width);
552

Jekyll Wu's avatar
Jekyll Wu committed
553
    /**
554
555
     * Emitted when the user right clicks on the display, or right-clicks
     * with the Shift key held down if usesMouseTracking() is true.
556
557
558
     *
     * This can be used to display a context menu.
     */
Kurt Hindenburg's avatar
Kurt Hindenburg committed
559
    void configureRequest(const QPoint &position);
560

561
    /**
Jekyll Wu's avatar
Jekyll Wu committed
562
563
564
     * When a shortcut which is also a valid terminal key sequence is pressed while
     * the terminal widget  has focus, this signal is emitted to allow the host to decide
     * whether the shortcut should be overridden.
565
566
567
568
569
     * When the shortcut is overridden, the key sequence will be sent to the terminal emulation instead
     * and the action associated with the shortcut will not be triggered.
     *
     * @p override is set to false by default and the shortcut will be triggered as normal.
     */
Kurt Hindenburg's avatar
Kurt Hindenburg committed
570
    void overrideShortcutCheck(QKeyEvent *keyEvent, bool &override);
571

Kurt Hindenburg's avatar
Kurt Hindenburg committed
572
    void sendStringToEmu(const QByteArray &local8BitString);
573

574
    void compositeFocusChanged(bool focused);
575

576
protected:
577
    // events
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
    bool event(QEvent *event) override;
    void paintEvent(QPaintEvent *pe) override;
    void showEvent(QShowEvent *event) override;
    void hideEvent(QHideEvent *event) override;
    void resizeEvent(QResizeEvent *event) override;
    void contextMenuEvent(QContextMenuEvent *event) override;
    void focusInEvent(QFocusEvent *event) override;
    void focusOutEvent(QFocusEvent *event) override;
    void keyPressEvent(QKeyEvent *event) override;
    void keyReleaseEvent(QKeyEvent *event) override;
    void leaveEvent(QEvent *event) override;
    void mouseDoubleClickEvent(QMouseEvent *ev) override;
    void mousePressEvent(QMouseEvent *ev) override;
    void mouseReleaseEvent(QMouseEvent *ev) override;
    void mouseMoveEvent(QMouseEvent *ev) override;
    void wheelEvent(QWheelEvent *ev) override;
    bool focusNextPrevChild(bool next) override;
595

596
597
598
    void fontChange(const QFont &);
    void extendSelection(const QPoint &position);

599
    // drag and drop
600
601
    void dragEnterEvent(QDragEnterEvent *event) override;
    void dropEvent(QDropEvent *event) override;
602
    void doDrag();
Kurt Hindenburg's avatar
Kurt Hindenburg committed
603
604
605
    enum DragState {
        diNone, diPending, diDragging
    };
606

607
    struct DragInfo {
Kurt Hindenburg's avatar
Kurt Hindenburg committed
608
609
610
        DragState state;
        QPoint start;
        QDrag *dragObject;
611
    } _dragInfo;
612

613
614
615
    // classifies the 'ch' into one of three categories
    // and returns a character to indicate which category it is in
    //
Jekyll Wu's avatar
Jekyll Wu committed
616
    //     - A space (returns ' ')
617
618
    //     - Part of a word (returns 'a')
    //     - Other characters (returns the input character)
Kurt Hindenburg's avatar
Kurt Hindenburg committed
619
    QChar charClass(const Character &ch) const;
620
621
622

    void clearImage();

623
    void mouseTripleClickEvent(QMouseEvent *ev);
624
    void selectLine(QPoint pos, bool entireLine);
625

626
    // reimplemented
627
628
    void inputMethodEvent(QInputMethodEvent *event) override;
    QVariant inputMethodQuery(Qt::InputMethodQuery query) const override;
629

630
631
    void onColorsChanged();

632
protected Q_SLOTS:
633

634
    void scrollBarPositionChanged(int value);
635
    void blinkTextEvent();
Stephan Binner's avatar
Stephan Binner committed
636
    void blinkCursorEvent();
637
    void highlightScrolledLinesEvent();
638

639
private Q_SLOTS:
640

641
    void swapFGBGColors();
Harald Hvaal's avatar
Harald Hvaal committed
642
    void viewScrolledByUser();
643

644
645
    void dismissOutputSuspendedMessage();

646
private:
647
648
    Q_DISABLE_COPY(TerminalDisplay)

649
650
651
652
    // -- Drawing helpers --

    // divides the part of the display specified by 'rect' into
    // fragments according to their colors and styles and calls
653
654
    // drawTextFragment() or drawPrinterFriendlyTextFragment()
    // to draw the fragments
Kurt Hindenburg's avatar
Kurt Hindenburg committed
655
    void drawContents(QPainter &painter, const QRect &rect);
Harald Hvaal's avatar
Harald Hvaal committed
656
    // draw a transparent rectangle over the line of the current match
Kurt Hindenburg's avatar
Kurt Hindenburg committed
657
    void drawCurrentResultRect(QPainter &painter);
658
659
660
    // draw a thin highlight on the left of the screen for lines that have been scrolled into view
    void highlightScrolledLines(QPainter& painter);
    // compute which region need to be repainted for scrolled lines highlight
661
    QRegion highlightScrolledLinesRegion(bool nothingChanged);
662

663
664
    // draws a section of text, all the text in this section
    // has a common color and style
Kurt Hindenburg's avatar
Kurt Hindenburg committed
665
666
    void drawTextFragment(QPainter &painter, const QRect &rect, const QString &text,
                          const Character *style);
667

Kurt Hindenburg's avatar
Kurt Hindenburg committed
668
669
    void drawPrinterFriendlyTextFragment(QPainter &painter, const QRect &rect, const QString &text,
                                         const Character *style);
670
    // draws the background for a text fragment
Robert Knight's avatar
   
Robert Knight committed
671
672
673
    // if useOpacitySetting is true then the color's alpha value will be set to
    // the display's transparency (set with setOpacity()), otherwise the background
    // will be drawn fully opaque
674
    void drawBackground(QPainter &painter, const QRect &rect, const QColor &backgroundColor,
675
                        bool useOpacitySetting);
676
    // draws the cursor character
Kurt Hindenburg's avatar
Kurt Hindenburg committed
677
    void drawCursor(QPainter &painter, const QRect &rect, const QColor &foregroundColor,
678
                    const QColor &backgroundColor, QColor &characterColor);
679
    // draws the characters or line graphics in a text fragment
Kurt Hindenburg's avatar
Kurt Hindenburg committed
680
    void drawCharacters(QPainter &painter, const QRect &rect, const QString &text,
681
                        const Character *style, const QColor &characterColor);
682
    // draws a string of line graphics
Kurt Hindenburg's avatar
Kurt Hindenburg committed
683
684
    void drawLineCharString(QPainter &painter, int x, int y, const QString &str,
                            const Character *attributes);
685

686
    // draws the preedit string for input methods
Kurt Hindenburg's avatar
Kurt Hindenburg committed
687
    void drawInputMethodPreeditString(QPainter &painter, const QRect &rect);
688

689
690
    // --

691

692
693
694

    // the area where the preedit string for input methods will be draw
    QRect preeditRect() const;
695

696
697
698
699
    // shows a notification window in the middle of the widget indicating the terminal's
    // current size in columns and lines
    void showResizeNotification();

700
701
702
703
    // applies changes to scrollbarLocation to the scroll bar and
    // if @propagate is true, propagates size information
    void applyScrollBarPosition(bool propagate = true);

Jekyll Wu's avatar
Jekyll Wu committed
704
705
    // scrolls the image by a number of lines.
    // 'lines' may be positive ( to scroll the image down )
706
    // or negative ( to scroll the image up )
707
708
709
    // 'region' is the part of the image to scroll - currently only
    // the top, bottom and height of 'region' are taken into account,
    // the left and right are ignored.
710
    void scrollImage(int lines, const QRect &screenWindowRegion);
711

712
713
714
    void calcGeometry();
    void propagateSize();
    void updateImageSize();
715
    void makeImage();
716

Kurt Hindenburg's avatar
Kurt Hindenburg committed
717
    void paintFilters(QPainter &painter);
718

719
720
    void setupHeaderVisibility();

721
722
    // returns the position of the cursor in columns and lines
    QPoint cursorPosition() const;
723

724
725
726
    // returns true if the cursor's position is on display.
    bool isCursorOnDisplay() const;

727
728
    // redraws the cursor
    void updateCursor();
729

730
    bool handleShortcutOverrideEvent(QKeyEvent *keyEvent);
731

732
    void doPaste(QString text, bool appendReturn);
Jekyll Wu's avatar
Jekyll Wu committed
733

734
    void processMidButtonClick(QMouseEvent *ev);
735

736
737
    QPoint findLineStart(const QPoint &pnt);
    QPoint findLineEnd(const QPoint &pnt);
738
739
    QPoint findWordStart(const QPoint &pnt);
    QPoint findWordEnd(const QPoint &pnt);
740

741
742
743
    // Uses the current settings for trimming whitespace and preserving linebreaks to create a proper flag value for Screen
    Screen::DecodingOptions currentDecodingOptions();

744
    // Boilerplate setup for MessageWidget
745
    KMessageWidget* createMessageWidget(const QString &text);
746

747
748
    int loc(int x, int y) const;

749
    // the window onto the terminal screen which this display
Jekyll Wu's avatar
Jekyll Wu committed
750
    // is currently showing.
751
    QPointer<ScreenWindow> _screenWindow;
752

753
    bool _bellMasked;
754

755
    QVBoxLayout *_verticalLayout;
756

757
    bool _fixedFont; // has fixed pitch
Kurt Hindenburg's avatar
Kurt Hindenburg committed
758
759
760
    int _fontHeight;      // height
    int _fontWidth;      // width
    int _fontAscent;      // ascend
761
    bool _boldIntense;   // Whether intense colors should be rendered with bold font
762

763
764
    int _lines;      // the number of lines that can be displayed in the widget
    int _columns;    // the number of columns that can be displayed in the widget
765

766
    int _usedLines;  // the number of lines that are actually being used, this will be less
Kurt Hindenburg's avatar
Kurt Hindenburg committed
767
768
    // than 'lines' if the character image provided with setImage() is smaller
    // than the maximum image size which can be displayed
769

770
    int _usedColumns; // the number of columns that are actually being used, this will be less
Kurt Hindenburg's avatar
Kurt Hindenburg committed
771
772
    // than 'columns' if the character image provided with setImage() is smaller
    // than the maximum image size which can be displayed
773

774
    QRect _contentRect;
Kurt Hindenburg's avatar
Kurt Hindenburg committed
775
    Character *_image; // [lines][columns]
Kurt Hindenburg's avatar
Kurt Hindenburg committed
776
    // only the area [usedLines][usedColumns] in the image contains valid data
777

778
779
780
781
    int _imageSize;
    QVector<LineProperty> _lineProperties;

    ColorEntry _colorTable[TABLE_COLORS];
782

783
    uint _randomSeed;
784
785

    bool _resizing;
786
    bool _showTerminalSizeHint;
787
    bool _bidiEnabled;
788
    bool _usesMouseTracking;
789
    bool _alternateScrolling;
790
    bool _bracketedPasteMode;
791

Kurt Hindenburg's avatar
Kurt Hindenburg committed
792
793
794
795
796
797
798
799
    QPoint _iPntSel;  // initial selection point
    QPoint _pntSel;  // current selection point
    QPoint _tripleSelBegin;  // help avoid flicker
    int _actSel;     // selection state
    bool _wordSelectionMode;
    bool _lineSelectionMode;
    bool _preserveLineBreaks;
    bool _columnSelectionMode;
800

801
    bool _autoCopySelectedText;
802
    bool _copyTextAsHTML;
803
804
    Enum::MiddleClickPasteModeEnum _middleClickPasteMode;

Kurt Hindenburg's avatar
Kurt Hindenburg committed
805
    QScrollBar *_scrollBar;
806
    Enum::ScrollBarPositionEnum _scrollbarLocation;
807
    bool _scrollFullPage;
Kurt Hindenburg's avatar
Kurt Hindenburg committed
808
809
    QString _wordCharacters;
    int _bellMode;
810

811
812
    bool _allowBlinkingText;  // allow text to blink
    bool _allowBlinkingCursor;  // allow cursor to blink
813
814
    bool _textBlinking;   // text is blinking, hide it when drawing
    bool _cursorBlinking;     // cursor is blinking, hide it when drawing
815
    bool _hasTextBlinker; // has characters to blink
Kurt Hindenburg's avatar
Kurt Hindenburg committed
816
817
    QTimer *_blinkTextTimer;
    QTimer *_blinkCursorTimer;
818

819
    Qt::KeyboardModifiers _urlHintsModifiers;
820
    bool _showUrlHint;
821
    bool _reverseUrlHints;
822
    bool _openLinksByDirectClick;     // Open URL and hosts by single mouse click
823

824
    bool _ctrlRequiredForDrag; // require Ctrl key for drag selected text
825
    bool _dropUrlsAsText; // always paste URLs as text without showing copy/move menu
826

827
    Enum::TripleClickModeEnum _tripleClickMode;
828
    bool _possibleTripleClick;  // is set in mouseDoubleClickEvent and deleted
Kurt Hindenburg's avatar
Kurt Hindenburg committed
829
    // after QApplication::doubleClickInterval() delay
830

Kurt Hindenburg's avatar
Kurt Hindenburg committed
831
832
    QLabel *_resizeWidget;
    QTimer *_resizeTimer;
833

834
    bool _flowControlWarningEnabled;
Robert Knight's avatar
   
Robert Knight committed
835
836
837

    //widgets related to the warning message that appears when the user presses Ctrl+S to suspend
    //terminal output - informing them what has happened and how to resume output
838
    KMessageWidget *_outputSuspendedMessageWidget;
839

840
    uint _lineSpacing;
841

842
    QSize _size;
843

844
845
    QRgb _blendColor;

846
    ColorScheme const* _colorScheme;
847
848
    ColorSchemeWallpaper::Ptr _wallpaper;

Robert Knight's avatar
   
Robert Knight committed
849
850
    // list of filters currently applied to the display.  used for links and
    // search highlight
Kurt Hindenburg's avatar
Kurt Hindenburg committed
851
    TerminalImageFilterChain *_filterChain;
852
    bool _filterUpdateRequired;
853

854
    Enum::CursorShapeEnum _cursorShape;
Robert Knight's avatar
   
Robert Knight committed
855

856
    // cursor color. If it is invalid (by default) then the foreground
Robert Knight's avatar
   
Robert Knight committed
857
    // color of the character under the cursor is used
Kurt Hindenburg's avatar
Kurt Hindenburg committed
858
    QColor _cursorColor;
Robert Knight's avatar
   
Robert Knight committed
859

860
861
862
863
    // cursor text color. If it is invalid (by default) then the background
    // color of the character under the cursor is used
    QColor _cursorTextColor;

Kurt Hindenburg's avatar
Kurt Hindenburg committed
864
    struct InputMethodData {
865
866
867
868
869
        QString preeditString;
        QRect previousPreeditRect;
    };
    InputMethodData _inputMethodData;

870
    bool _antialiasText;   // do we anti-alias or not
871
    bool _useFontLineCharacters;
872

873
874
    bool _printerFriendly; // are we currently painting to a printer in black/white mode

Robert Knight's avatar
   
Robert Knight committed
875
    //the delay in milliseconds between redrawing blinking text
876
    static const int TEXT_BLINK_DELAY = 500;
Jekyll Wu's avatar
Jekyll Wu committed
877
878
879
880

    //the duration of the size hint in milliseconds
    static const int SIZE_HINT_DURATION = 1000;

Kurt Hindenburg's avatar
Kurt Hindenburg committed
881
    SessionController *_sessionController;
882