2
Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
3
Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
5
This program is free software; you can redistribute it and/or modify
6
it under the terms of the GNU General Public License as published by
7
the Free Software Foundation; either version 2 of the License, or
8
(at your option) any later version.
10
This program is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
GNU General Public License for more details.
15
You should have received a copy of the GNU General Public License
16
along with this program; if not, write to the Free Software
17
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21
#ifndef TERMINALDISPLAY_H
22
#define TERMINALDISPLAY_H
25
#include <QtGui/QColor>
26
#include <QtCore/QPointer>
27
#include <QtGui/QWidget>
30
#include "Character.h"
31
#include "konsole_export.h"
32
#include "ScreenWindow.h"
33
#include "ColorScheme.h"
34
#include "Enumeration.h"
37
class QDragEnterEvent;
52
class TerminalImageFilterChain;
53
class SessionController;
56
* A widget which displays output from a terminal emulation and sends input keypresses and mouse activity
59
* When the terminal emulation receives new output from the program running in the terminal,
60
* it will update the display by calling updateImage().
62
* TODO More documentation
64
class KONSOLEPRIVATE_EXPORT TerminalDisplay : public QWidget
69
/** Constructs a new terminal display widget with the specified parent. */
70
explicit TerminalDisplay(QWidget* parent = 0);
71
virtual ~TerminalDisplay();
73
/** Returns the terminal color palette used by the display. */
74
const ColorEntry* colorTable() const;
75
/** Sets the terminal color palette used by the display. */
76
void setColorTable(const ColorEntry table[]);
78
* Sets the seed used to generate random colors for the display
79
* (in color schemes that support them).
81
void setRandomSeed(uint seed);
83
* Returns the seed used to generate random colors for the display
84
* (in color schemes that support them).
86
uint randomSeed() const;
88
/** Sets the opacity of the terminal display. */
89
void setOpacity(qreal opacity);
91
/** Sets the background picture */
92
void setWallpaper(ColorSchemeWallpaper::Ptr p);
95
* Specifies whether the terminal display has a vertical scroll bar, and if so whether it
96
* is shown on the left or right side of the display.
98
void setScrollBarPosition(Enum::ScrollBarPositionEnum position);
101
* Sets the current position and range of the display's scroll bar.
103
* @param cursor The position of the scroll bar's thumb.
104
* @param lines The maximum value of the scroll bar.
106
void setScroll(int cursor, int lines);
109
* Returns the display's filter chain. When the image for the display is updated,
110
* the text is passed through each filter in the chain. Each filter can define
111
* hotspots which correspond to certain strings (such as URLs or particular words).
112
* Depending on the type of the hotspots created by the filter ( returned by Filter::Hotspot::type() )
113
* the view will draw visual cues such as underlines on mouse-over for links or translucent
114
* rectangles for markers.
116
* To add a new filter to the view, call:
117
* viewWidget->filterChain()->addFilter( filterObject );
119
FilterChain* filterChain() const;
122
* Updates the filters in the display's filter chain. This will cause
123
* the hotspots to be updated to match the current image.
125
* WARNING: This function can be expensive depending on the
126
* image size and number of filters in the filterChain()
128
* TODO - This API does not really allow efficient usage. Revise it so
129
* that the processing can be done in a better way.
132
* - Area of interest may be known ( eg. mouse cursor hovering
135
void processFilters();
138
* Returns a list of menu actions created by the filters for the content
139
* at the given @p position.
141
QList<QAction*> filterActions(const QPoint& position);
143
/** Specifies whether or not the cursor can blink. */
144
void setBlinkingCursorEnabled(bool blink);
145
/** Returns true if the cursor is allowed to blink or false otherwise. */
146
bool blinkingCursorEnabled() const {
147
return _allowBlinkingCursor;
150
/** Specifies whether or not text can blink. */
151
void setBlinkingTextEnabled(bool blink);
153
void setCtrlDrag(bool enable) {
156
bool ctrlDrag() const {
160
/** Sets how the text is selected when the user triple clicks within the display. */
161
void setTripleClickMode(Enum::TripleClickModeEnum mode) {
162
_tripleClickMode = mode;
164
/** See setTripleClickSelectionMode() */
165
Enum::TripleClickModeEnum tripleClickMode() const {
166
return _tripleClickMode;
170
* Specifies whether links and email addresses should be underlined when
171
* hovered by the mouse. Defaults to true.
173
void setUnderlineLinks(bool value) {
174
_underlineLinks = value;
177
* Returns true if links and email addresses should be underlined when
178
* hovered by the mouse.
180
bool getUnderlineLinks() const {
181
return _underlineLinks;
184
void setLineSpacing(uint);
185
uint lineSpacing() const;
187
void setSessionController(SessionController* controller);
190
* Sets the shape of the keyboard cursor. This is the cursor drawn
191
* at the position in the terminal where keyboard input will appear.
193
* In addition the terminal display widget also has a cursor for
194
* the mouse pointer, which can be set using the QWidget::setCursor()
197
* Defaults to BlockCursor
199
void setKeyboardCursorShape(Enum::CursorShapeEnum shape);
201
* Returns the shape of the keyboard cursor. See setKeyboardCursorShape()
203
Enum::CursorShapeEnum keyboardCursorShape() const;
206
* Sets the color used to draw the keyboard cursor.
208
* The keyboard cursor defaults to using the foreground color of the character
211
* @param color By default, the widget uses the color of the
212
* character under the cursor to draw the cursor, and inverts the
213
* color of that character to make sure it is still readable. If @p
214
* color is a valid QColor, the widget uses that color to draw the
215
* cursor. If @p color is not an valid QColor, the widget falls back
216
* to the default behavior.
218
void setKeyboardCursorColor(const QColor& color);
221
* Returns the color of the keyboard cursor, or an invalid color if the keyboard
222
* cursor color is set to change according to the foreground color of the character
225
QColor keyboardCursorColor() const;
228
* Returns the number of lines of text which can be displayed in the widget.
230
* This will depend upon the height of the widget and the current font.
237
* Returns the number of characters of text which can be displayed on
238
* each line in the widget.
240
* This will depend upon the width of the widget and the current font.
243
int columns() const {
248
* Returns the height of the characters in the font used to draw the text in the display.
250
int fontHeight() const {
254
* Returns the width of the characters in the display.
255
* This assumes the use of a fixed-width font.
257
int fontWidth() const {
261
void setSize(int columns, int lines);
262
void setFixedSize(int columns, int lines);
265
QSize sizeHint() const;
268
* Sets which characters, in addition to letters and numbers,
269
* are regarded as being part of a word for the purposes
270
* of selecting words in the display by double clicking on them.
272
* The word boundaries occur at the first and last characters which
273
* are either a letter, number, or a character in @p wc
275
* @param wc An array of characters which are to be considered parts
276
* of a word ( in addition to letters and numbers ).
278
void setWordCharacters(const QString& wc);
280
* Returns the characters which are considered part of a word for the
281
* purpose of selecting words in the display with the mouse.
283
* @see setWordCharacters()
285
QString wordCharacters() const {
286
return _wordCharacters;
290
* Sets the type of effect used to alert the user when a 'bell' occurs in the
293
* The terminal session can trigger the bell effect by calling bell() with
296
void setBellMode(int mode);
298
* Returns the type of effect used to alert the user when a 'bell' occurs in
299
* the terminal session.
303
int bellMode() const;
305
/** Play a visual bell for prompt or warning. */
309
* Reimplemented. Has no effect. Use setVTFont() to change the font
310
* used to draw characters in the display.
312
virtual void setFont(const QFont &);
314
/** Returns the font used to draw characters in the display */
320
* Sets the font used to draw the display. Has no effect if @p font
321
* is larger than the size of the display itself.
323
void setVTFont(const QFont& font);
325
/** Increases the font size */
326
void increaseFontSize();
328
/** Decreases the font size */
329
void decreaseFontSize();
332
* Specified whether anti-aliasing of text in the terminal display
333
* is enabled or not. Defaults to enabled.
335
void setAntialias(bool value) {
336
_antialiasText = value;
339
* Returns true if anti-aliasing of text in the terminal is enabled.
341
bool antialias() const {
342
return _antialiasText;
346
* Specifies whether characters with intense colors should be rendered
347
* as bold. Defaults to true.
349
void setBoldIntense(bool value) {
350
_boldIntense = value;
353
* Returns true if characters with intense colors are rendered in bold.
355
bool getBoldIntense() const {
360
* Sets whether or not the current height and width of the
361
* terminal in lines and columns is displayed whilst the widget
364
void setShowTerminalSizeHint(bool on) {
365
_showTerminalSizeHint = on;
368
* Returns whether or not the current height and width of
369
* the terminal in lines and columns is displayed whilst the widget
372
bool showTerminalSizeHint() const {
373
return _showTerminalSizeHint;
377
* Sets the status of the BiDi rendering inside the terminal display.
378
* Defaults to disabled.
380
void setBidiEnabled(bool set) {
382
// See bug 280896 for more info
383
#if QT_VERSION >= 0x040800
392
* Returns the status of the BiDi rendering in this widget.
394
bool isBidiEnabled() const {
399
* Sets the terminal screen section which is displayed in this widget.
400
* When updateImage() is called, the display fetches the latest character image from the
401
* the associated terminal screen window.
403
* In terms of the model-view paradigm, the ScreenWindow is the model which is rendered
404
* by the TerminalDisplay.
406
void setScreenWindow(ScreenWindow* window);
407
/** Returns the terminal screen section which is displayed in this widget. See setScreenWindow() */
408
ScreenWindow* screenWindow() const;
412
* Scrolls current ScreenWindow
414
* it's needed for proper handling scroll commands in the Vt102Emulation class
416
void scrollScreenWindow(enum ScreenWindow::RelativeScrollMode mode , int amount);
419
* Causes the terminal display to fetch the latest character image from the associated
420
* terminal screen ( see setScreenWindow() ) and redraw the display.
424
* Causes the terminal display to fetch the latest line status flags from the
425
* associated terminal screen ( see setScreenWindow() ).
427
void updateLineProperties();
429
void setAutoCopySelectedText(bool enabled);
431
void setMiddleClickPasteMode(Enum::MiddleClickPasteModeEnum mode);
433
/** Copies the selected text to the X11 Selection. */
434
void copyToX11Selection();
436
/** Copies the selected text to the system clipboard. */
437
void copyToClipboard();
440
* Pastes the content of the clipboard into the
443
void pasteFromClipboard(bool appendEnter = false);
445
* Pastes the content of the X11 selection into the
448
void pasteFromX11Selection(bool appendEnter = false);
451
* Changes whether the flow control warning box should be shown when the flow control
452
* stop key (Ctrl+S) are pressed.
454
void setFlowControlWarningEnabled(bool enabled);
456
* Returns true if the flow control warning box is enabled.
457
* See outputSuspended() and setFlowControlWarningEnabled()
459
bool flowControlWarningEnabled() const {
460
return _flowControlWarningEnabled;
464
* Causes the widget to display or hide a message informing the user that terminal
465
* output has been suspended (by using the flow control key combination Ctrl+S)
467
* @param suspended True if terminal output has been suspended and the warning message should
468
* be shown or false to indicate that terminal output has been resumed and that
469
* the warning message should disappear.
471
void outputSuspended(bool suspended);
474
* Sets whether the program whose output is being displayed in the view
475
* is interested in mouse events.
477
* If this is set to true, mouse signals will be emitted by the view when the user clicks, drags
478
* or otherwise moves the mouse inside the view.
479
* The user interaction needed to create selections will also change, and the user will be required
480
* to hold down the shift key to create a selection or perform other mouse activities inside the
481
* view area - since the program running in the terminal is being allowed to handle normal mouse
484
* @param usesMouse Set to true if the program running in the terminal is interested in mouse events
485
* or false otherwise.
487
void setUsesMouse(bool usesMouse);
489
/** See setUsesMouse() */
490
bool usesMouse() const;
493
* Shows a notification that a bell event has occurred in the terminal.
494
* TODO: More documentation here
496
void bell(const QString& message);
499
* Sets the background of the display to the specified color.
500
* @see setColorTable(), setForegroundColor()
502
void setBackgroundColor(const QColor& color);
505
* Sets the text of the display to the specified color.
506
* @see setColorTable(), setBackgroundColor()
508
void setForegroundColor(const QColor& color);
513
* Emitted when the user presses a key whilst the terminal widget has focus.
515
void keyPressedSignal(QKeyEvent* event);
518
* A mouse event occurred.
519
* @param button The mouse button (0 for left button, 1 for middle button, 2 for right button, 3 for release)
520
* @param column The character column where the event occurred
521
* @param line The character row where the event occurred
522
* @param eventType The type of event. 0 for a mouse press / release or 1 for mouse motion
524
void mouseSignal(int button, int column, int line, int eventType);
525
void changedFontMetricSignal(int height, int width);
526
void changedContentSizeSignal(int height, int width);
529
* Emitted when the user right clicks on the display, or right-clicks with the Shift
530
* key held down if usesMouse() is true.
532
* This can be used to display a context menu.
534
void configureRequest(const QPoint& position);
537
* When a shortcut which is also a valid terminal key sequence is pressed while
538
* the terminal widget has focus, this signal is emitted to allow the host to decide
539
* whether the shortcut should be overridden.
540
* When the shortcut is overridden, the key sequence will be sent to the terminal emulation instead
541
* and the action associated with the shortcut will not be triggered.
543
* @p override is set to false by default and the shortcut will be triggered as normal.
545
void overrideShortcutCheck(QKeyEvent* keyEvent, bool& override);
547
void sendStringToEmu(const char*);
550
virtual bool event(QEvent* event);
552
virtual void paintEvent(QPaintEvent* event);
554
virtual void showEvent(QShowEvent* event);
555
virtual void hideEvent(QHideEvent* event);
556
virtual void resizeEvent(QResizeEvent* event);
558
virtual void contextMenuEvent(QContextMenuEvent* event);
560
virtual void fontChange(const QFont&);
561
virtual void focusInEvent(QFocusEvent* event);
562
virtual void focusOutEvent(QFocusEvent* event);
563
virtual void keyPressEvent(QKeyEvent* event);
564
virtual void mouseDoubleClickEvent(QMouseEvent* event);
565
virtual void mousePressEvent(QMouseEvent* event);
566
virtual void mouseReleaseEvent(QMouseEvent* event);
567
virtual void mouseMoveEvent(QMouseEvent* event);
568
virtual void extendSelection(const QPoint& pos);
569
virtual void wheelEvent(QWheelEvent* event);
571
virtual bool focusNextPrevChild(bool next);
574
virtual void dragEnterEvent(QDragEnterEvent* event);
575
virtual void dropEvent(QDropEvent* event);
577
enum DragState { diNone, diPending, diDragging };
585
// classifies the 'ch' into one of three categories
586
// and returns a character to indicate which category it is in
588
// - A space (returns ' ')
589
// - Part of a word (returns 'a')
590
// - Other characters (returns the input character)
591
QChar charClass(const Character& ch) const;
595
void mouseTripleClickEvent(QMouseEvent* event);
598
virtual void inputMethodEvent(QInputMethodEvent* event);
599
virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) const;
603
void scrollBarPositionChanged(int value);
604
void blinkTextEvent();
605
void blinkCursorEvent();
610
void swapFGBGColors();
611
void tripleClickTimeout(); // resets possibleTripleClick
614
* Called from the drag'n'drop popup. Causes the dropped URLs to be pasted as text.
616
void dropMenuPasteActionTriggered();
618
void dropMenuCdActionTriggered();
621
// -- Drawing helpers --
623
// divides the part of the display specified by 'rect' into
624
// fragments according to their colors and styles and calls
625
// drawTextFragment() to draw the fragments
626
void drawContents(QPainter& painter, const QRect& rect);
627
// draws a section of text, all the text in this section
628
// has a common color and style
629
void drawTextFragment(QPainter& painter, const QRect& rect,
630
const QString& text, const Character* style);
631
// draws the background for a text fragment
632
// if useOpacitySetting is true then the color's alpha value will be set to
633
// the display's transparency (set with setOpacity()), otherwise the background
634
// will be drawn fully opaque
635
void drawBackground(QPainter& painter, const QRect& rect, const QColor& color,
636
bool useOpacitySetting);
637
// draws the cursor character
638
void drawCursor(QPainter& painter, const QRect& rect , const QColor& foregroundColor,
639
const QColor& backgroundColor , bool& invertColors);
640
// draws the characters or line graphics in a text fragment
641
void drawCharacters(QPainter& painter, const QRect& rect, const QString& text,
642
const Character* style, bool invertCharacterColor);
643
// draws a string of line graphics
644
void drawLineCharString(QPainter& painter, int x, int y,
645
const QString& str, const Character* attributes);
647
// draws the preedit string for input methods
648
void drawInputMethodPreeditString(QPainter& painter , const QRect& rect);
652
// maps an area in the character image to an area on the widget
653
QRect imageToWidget(const QRect& imageArea) const;
655
// maps a point on the widget to the position ( ie. line and column )
656
// of the character at that point.
657
void getCharacterPosition(const QPoint& widgetPoint, int& line, int& column) const;
659
// the area where the preedit string for input methods will be draw
660
QRect preeditRect() const;
662
// shows a notification window in the middle of the widget indicating the terminal's
663
// current size in columns and lines
664
void showResizeNotification();
666
// scrolls the image by a number of lines.
667
// 'lines' may be positive ( to scroll the image down )
668
// or negative ( to scroll the image up )
669
// 'region' is the part of the image to scroll - currently only
670
// the top, bottom and height of 'region' are taken into account,
671
// the left and right are ignored.
672
void scrollImage(int lines , const QRect& region);
675
void propagateSize();
676
void updateImageSize();
679
void paintFilters(QPainter& painter);
681
// returns a region covering all of the areas of the widget which contain
683
QRegion hotSpotRegion() const;
685
// returns the position of the cursor in columns and lines
686
QPoint cursorPosition() const;
688
// redraws the cursor
691
bool handleShortcutOverrideEvent(QKeyEvent* event);
693
void doPaste(QString text, bool appendReturn);
695
void processMidButtonClick(QMouseEvent* event);
697
// the window onto the terminal screen which this display
698
// is currently showing.
699
QPointer<ScreenWindow> _screenWindow;
703
QGridLayout* _gridLayout;
705
bool _fixedFont; // has fixed pitch
706
int _fontHeight; // height
707
int _fontWidth; // width
708
int _fontAscent; // ascend
709
bool _boldIntense; // Whether intense colors should be rendered with bold font
711
int _leftMargin; // offset
712
int _topMargin; // offset
714
int _lines; // the number of lines that can be displayed in the widget
715
int _columns; // the number of columns that can be displayed in the widget
717
int _usedLines; // the number of lines that are actually being used, this will be less
718
// than 'lines' if the character image provided with setImage() is smaller
719
// than the maximum image size which can be displayed
721
int _usedColumns; // the number of columns that are actually being used, this will be less
722
// than 'columns' if the character image provided with setImage() is smaller
723
// than the maximum image size which can be displayed
727
Character* _image; // [lines][columns]
728
// only the area [usedLines][usedColumns] in the image contains valid data
731
QVector<LineProperty> _lineProperties;
733
ColorEntry _colorTable[TABLE_COLORS];
737
bool _showTerminalSizeHint;
741
QPoint _iPntSel; // initial selection point
742
QPoint _pntSel; // current selection point
743
QPoint _tripleSelBegin; // help avoid flicker
744
int _actSel; // selection state
745
bool _wordSelectionMode;
746
bool _lineSelectionMode;
747
bool _preserveLineBreaks;
748
bool _columnSelectionMode;
750
bool _autoCopySelectedText;
751
Enum::MiddleClickPasteModeEnum _middleClickPasteMode;
753
QScrollBar* _scrollBar;
754
Enum::ScrollBarPositionEnum _scrollbarLocation;
755
QString _wordCharacters;
758
bool _allowBlinkingText; // allow text to blink
759
bool _allowBlinkingCursor; // allow cursor to blink
760
bool _textBlinking; // text is blinkingi, hide it when drawing
761
bool _cursorBlinking; // cursor is blinking, hide it whe drawing
762
bool _hasTextBlinker; // has characters to blink
763
QTimer* _blinkTextTimer;
764
QTimer* _blinkCursorTimer;
766
bool _underlineLinks; // Underline URL and hosts on mouse hover
767
bool _isFixedSize; // columns/lines are locked.
769
bool _ctrlDrag; // require Ctrl key for drag selected text
771
Enum::TripleClickModeEnum _tripleClickMode;
772
bool _possibleTripleClick; // is set in mouseDoubleClickEvent and deleted
773
// after QApplication::doubleClickInterval() delay
775
QLabel* _resizeWidget;
776
QTimer* _resizeTimer;
778
bool _flowControlWarningEnabled;
780
//widgets related to the warning message that appears when the user presses Ctrl+S to suspend
781
//terminal output - informing them what has happened and how to resume output
782
QLabel* _outputSuspendedLabel;
790
ColorSchemeWallpaper::Ptr _wallpaper;
792
// list of filters currently applied to the display. used for links and
794
TerminalImageFilterChain* _filterChain;
795
QRegion _mouseOverHotspotArea;
797
Enum::CursorShapeEnum _cursorShape;
799
// cursor color. If it is invalid (by default) then the foreground
800
// color of the character under the cursor is used
803
struct InputMethodData {
804
QString preeditString;
805
QRect previousPreeditRect;
807
InputMethodData _inputMethodData;
809
bool _antialiasText; // do we antialias or not
811
//the delay in milliseconds between redrawing blinking text
812
static const int TEXT_BLINK_DELAY = 500;
814
//the duration of the size hint in milliseconds
815
static const int SIZE_HINT_DURATION = 1000;
817
static const int DEFAULT_LEFT_MARGIN = 1;
818
static const int DEFAULT_TOP_MARGIN = 1;
820
SessionController* _sessionController;
821
friend class TerminalDisplayAccessible;
824
class AutoScrollHandler : public QObject
829
explicit AutoScrollHandler(QWidget* parent);
831
virtual void timerEvent(QTimerEvent* event);
832
virtual bool eventFilter(QObject* watched, QEvent* event);
834
QWidget* widget() const {
835
return static_cast<QWidget*>(parent());
841
#endif // TERMINALDISPLAY_H