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
31
#include "Character.h"
32
//#include "konsole_export.h"
33
#define KONSOLEPRIVATE_EXPORT
36
class QDragEnterEvent;
54
enum MotionAfterPasting
56
// No move screenwindow after pasting
57
NoMoveScreenWindow = 0,
58
// Move start of screenwindow after pasting
59
MoveStartScreenWindow = 1,
60
// Move end of screenwindow after pasting
61
MoveEndScreenWindow = 2
65
extern unsigned short vt100_graphics[32];
70
* A widget which displays output from a terminal emulation and sends input keypresses and mouse activity
73
* When the terminal emulation receives new output from the program running in the terminal,
74
* it will update the display by calling updateImage().
76
* TODO More documentation
78
class KONSOLEPRIVATE_EXPORT TerminalDisplay : public QWidget
83
/** Constructs a new terminal display widget with the specified parent. */
84
TerminalDisplay(QWidget *parent=0);
85
virtual ~TerminalDisplay();
87
/** Returns the terminal color palette used by the display. */
88
const ColorEntry* colorTable() const;
89
/** Sets the terminal color palette used by the display. */
90
void setColorTable(const ColorEntry table[]);
92
* Sets the seed used to generate random colors for the display
93
* (in color schemes that support them).
95
void setRandomSeed(uint seed);
97
* Returns the seed used to generate random colors for the display
98
* (in color schemes that support them).
100
uint randomSeed() const;
102
/** Sets the opacity of the terminal display. */
103
void setOpacity(qreal opacity);
106
* This enum describes the location where the scroll bar is positioned in the display widget.
108
enum ScrollBarPosition
110
/** Do not show the scroll bar. */
112
/** Show the scroll bar on the left side of the display. */
114
/** Show the scroll bar on the right side of the display. */
118
* Specifies whether the terminal display has a vertical scroll bar, and if so whether it
119
* is shown on the left or right side of the display.
121
void setScrollBarPosition(ScrollBarPosition position);
124
* Sets the current position and range of the display's scroll bar.
126
* @param cursor The position of the scroll bar's thumb.
127
* @param lines The maximum value of the scroll bar.
129
void setScroll(int cursor, int lines);
132
* Scroll to the bottom of the terminal (reset scrolling).
137
* Returns the display's filter chain. When the image for the display is updated,
138
* the text is passed through each filter in the chain. Each filter can define
139
* hotspots which correspond to certain strings (such as URLs or particular words).
140
* Depending on the type of the hotspots created by the filter ( returned by Filter::Hotspot::type() )
141
* the view will draw visual cues such as underlines on mouse-over for links or translucent
142
* rectangles for markers.
144
* To add a new filter to the view, call:
145
* viewWidget->filterChain()->addFilter( filterObject );
147
FilterChain* filterChain() const;
150
* Updates the filters in the display's filter chain. This will cause
151
* the hotspots to be updated to match the current image.
153
* WARNING: This function can be expensive depending on the
154
* image size and number of filters in the filterChain()
156
* TODO - This API does not really allow efficient usage. Revise it so
157
* that the processing can be done in a better way.
160
* - Area of interest may be known ( eg. mouse cursor hovering
163
void processFilters();
166
* Returns a list of menu actions created by the filters for the content
167
* at the given @p position.
169
QList<QAction*> filterActions(const QPoint& position);
171
/** Returns true if the cursor is set to blink or false otherwise. */
172
bool blinkingCursor() { return _hasBlinkingCursor; }
173
/** Specifies whether or not the cursor blinks. */
174
void setBlinkingCursor(bool blink);
176
/** Specifies whether or not text can blink. */
177
void setBlinkingTextEnabled(bool blink);
179
void setCtrlDrag(bool enable) { _ctrlDrag=enable; }
180
bool ctrlDrag() { return _ctrlDrag; }
183
* This enum describes the methods for selecting text when
184
* the user triple-clicks within the display.
188
/** Select the whole line underneath the cursor. */
190
/** Select from the current cursor position to the end of the line. */
191
SelectForwardsFromCursor
193
/** Sets how the text is selected when the user triple clicks within the display. */
194
void setTripleClickMode(TripleClickMode mode) { _tripleClickMode = mode; }
195
/** See setTripleClickSelectionMode() */
196
TripleClickMode tripleClickMode() { return _tripleClickMode; }
198
void setLineSpacing(uint);
199
uint lineSpacing() const;
201
void emitSelection(bool useXselection,bool appendReturn);
204
* This enum describes the available shapes for the keyboard cursor.
205
* See setKeyboardCursorShape()
207
enum KeyboardCursorShape
209
/** A rectangular block which covers the entire area of the cursor character. */
212
* A single flat line which occupies the space at the bottom of the cursor
217
* An cursor shaped like the capital letter 'I', similar to the IBeam
218
* cursor used in Qt/KDE text editors.
223
* Sets the shape of the keyboard cursor. This is the cursor drawn
224
* at the position in the terminal where keyboard input will appear.
226
* In addition the terminal display widget also has a cursor for
227
* the mouse pointer, which can be set using the QWidget::setCursor()
230
* Defaults to BlockCursor
232
void setKeyboardCursorShape(KeyboardCursorShape shape);
234
* Returns the shape of the keyboard cursor. See setKeyboardCursorShape()
236
KeyboardCursorShape keyboardCursorShape() const;
239
* Sets the color used to draw the keyboard cursor.
241
* The keyboard cursor defaults to using the foreground color of the character
244
* @param useForegroundColor If true, the cursor color will change to match
245
* the foreground color of the character underneath it as it is moved, in this
246
* case, the @p color parameter is ignored and the color of the character
247
* under the cursor is inverted to ensure that it is still readable.
248
* @param color The color to use to draw the cursor. This is only taken into
249
* account if @p useForegroundColor is false.
251
void setKeyboardCursorColor(bool useForegroundColor , const QColor& color);
254
* Returns the color of the keyboard cursor, or an invalid color if the keyboard
255
* cursor color is set to change according to the foreground color of the character
258
QColor keyboardCursorColor() const;
261
* Returns the number of lines of text which can be displayed in the widget.
263
* This will depend upon the height of the widget and the current font.
266
int lines() { return _lines; }
268
* Returns the number of characters of text which can be displayed on
269
* each line in the widget.
271
* This will depend upon the width of the widget and the current font.
274
int columns() { return _columns; }
277
* Returns the height of the characters in the font used to draw the text in the display.
279
int fontHeight() { return _fontHeight; }
281
* Returns the width of the characters in the display.
282
* This assumes the use of a fixed-width font.
284
int fontWidth() { return _fontWidth; }
286
void setSize(int cols, int lins);
287
void setFixedSize(int cols, int lins);
290
QSize sizeHint() const;
293
* Sets which characters, in addition to letters and numbers,
294
* are regarded as being part of a word for the purposes
295
* of selecting words in the display by double clicking on them.
297
* The word boundaries occur at the first and last characters which
298
* are either a letter, number, or a character in @p wc
300
* @param wc An array of characters which are to be considered parts
301
* of a word ( in addition to letters and numbers ).
303
void setWordCharacters(const QString& wc);
305
* Returns the characters which are considered part of a word for the
306
* purpose of selecting words in the display with the mouse.
308
* @see setWordCharacters()
310
QString wordCharacters() { return _wordCharacters; }
313
* Sets the type of effect used to alert the user when a 'bell' occurs in the
316
* The terminal session can trigger the bell effect by calling bell() with
319
void setBellMode(int mode);
321
* Returns the type of effect used to alert the user when a 'bell' occurs in
322
* the terminal session.
326
int bellMode() { return _bellMode; }
329
* This enum describes the different types of sounds and visual effects which
330
* can be used to alert the user when a 'bell' occurs in the terminal
335
/** A system beep. */
338
* KDE notification. This may play a sound, show a passive popup
339
* or perform some other action depending on the user's settings.
342
/** A silent, visual bell (eg. inverting the display's colors briefly) */
344
/** No bell effects */
348
void setSelection(const QString &t);
351
* Reimplemented. Has no effect. Use setVTFont() to change the font
352
* used to draw characters in the display.
354
virtual void setFont(const QFont &);
356
/** Returns the font used to draw characters in the display */
357
QFont getVTFont() { return font(); }
360
* Sets the font used to draw the display. Has no effect if @p font
361
* is larger than the size of the display itself.
363
void setVTFont(const QFont& font);
366
* Specified whether anti-aliasing of text in the terminal display
367
* is enabled or not. Defaults to enabled.
369
static void setAntialias( bool antialias ) { _antialiasText = antialias; }
371
* Returns true if anti-aliasing of text in the terminal is enabled.
373
static bool antialias() { return _antialiasText; }
376
* Specifies whether characters with intense colors should be rendered
377
* as bold. Defaults to true.
379
void setBoldIntense(bool value) { _boldIntense = value; }
381
* Returns true if characters with intense colors are rendered in bold.
383
bool getBoldIntense() { return _boldIntense; }
386
* Sets whether or not the current height and width of the
387
* terminal in lines and columns is displayed whilst the widget
390
void setTerminalSizeHint(bool on) { _terminalSizeHint=on; }
392
* Returns whether or not the current height and width of
393
* the terminal in lines and columns is displayed whilst the widget
396
bool terminalSizeHint() { return _terminalSizeHint; }
398
* Sets whether the terminal size display is shown briefly
399
* after the widget is first shown.
401
* See setTerminalSizeHint() , isTerminalSizeHint()
403
void setTerminalSizeStartup(bool on) { _terminalSizeStartup=on; }
406
* Sets the status of the BiDi rendering inside the terminal display.
407
* Defaults to disabled.
409
void setBidiEnabled(bool set) { _bidiEnabled=set; }
411
* Returns the status of the BiDi rendering in this widget.
413
bool isBidiEnabled() { return _bidiEnabled; }
416
* Sets the terminal screen section which is displayed in this widget.
417
* When updateImage() is called, the display fetches the latest character image from the
418
* the associated terminal screen window.
420
* In terms of the model-view paradigm, the ScreenWindow is the model which is rendered
421
* by the TerminalDisplay.
423
void setScreenWindow( ScreenWindow* window );
424
/** Returns the terminal screen section which is displayed in this widget. See setScreenWindow() */
425
ScreenWindow* screenWindow() const;
427
static bool HAVE_TRANSPARENCY;
429
void setMotionAfterPasting(MotionAfterPasting action);
430
int motionAfterPasting();
432
// maps a point on the widget to the position ( ie. line and column )
433
// of the character at that point.
434
void getCharacterPosition(const QPoint& widgetPoint,int& line,int& column) const;
436
// QMLTermWidget functions
437
QColor getBackgroundColor();
442
* Causes the terminal display to fetch the latest character image from the associated
443
* terminal screen ( see setScreenWindow() ) and redraw the display.
447
/** Essentially calles processFilters().
449
void updateFilters();
452
* Causes the terminal display to fetch the latest line status flags from the
453
* associated terminal screen ( see setScreenWindow() ).
455
void updateLineProperties();
457
/** Copies the selected text to the clipboard. */
458
void copyClipboard();
460
* Pastes the content of the clipboard into the
463
void pasteClipboard();
465
* Pastes the content of the selection into the
468
void pasteSelection();
471
* Changes whether the flow control warning box should be shown when the flow control
472
* stop key (Ctrl+S) are pressed.
474
void setFlowControlWarningEnabled(bool enabled);
476
* Returns true if the flow control warning box is enabled.
477
* See outputSuspended() and setFlowControlWarningEnabled()
479
bool flowControlWarningEnabled() const
480
{ return _flowControlWarningEnabled; }
483
* Causes the widget to display or hide a message informing the user that terminal
484
* output has been suspended (by using the flow control key combination Ctrl+S)
486
* @param suspended True if terminal output has been suspended and the warning message should
487
* be shown or false to indicate that terminal output has been resumed and that
488
* the warning message should disappear.
490
void outputSuspended(bool suspended);
493
* Sets whether the program whoose output is being displayed in the view
494
* is interested in mouse events.
496
* If this is set to true, mouse signals will be emitted by the view when the user clicks, drags
497
* or otherwise moves the mouse inside the view.
498
* The user interaction needed to create selections will also change, and the user will be required
499
* to hold down the shift key to create a selection or perform other mouse activities inside the
500
* view area - since the program running in the terminal is being allowed to handle normal mouse
503
* @param usesMouse Set to true if the program running in the terminal is interested in mouse events
504
* or false otherwise.
506
void setUsesMouse(bool usesMouse);
508
/** See setUsesMouse() */
509
bool usesMouse() const;
512
* Shows a notification that a bell event has occurred in the terminal.
513
* TODO: More documentation here
515
void bell(const QString& message);
518
* Sets the background of the display to the specified color.
519
* @see setColorTable(), setForegroundColor()
521
void setBackgroundColor(const QColor& color);
524
* Sets the text of the display to the specified color.
525
* @see setColorTable(), setBackgroundColor()
527
void setForegroundColor(const QColor& color);
529
void selectionChanged();
531
// QMLTermWidget slots: Used to simulate events from QML
532
void simulateKeyPress(QKeyEvent *event);
533
void simulateMousePress(QMouseEvent *event);
534
void simulateMouseMove(QMouseEvent *event);
535
void simulateMouseDoubleClick(QMouseEvent *event);
536
void simulateMouseRelease(QMouseEvent *event);
537
void simulateWheelEvent(QWheelEvent *event);
538
void simulateInputMethodEvent ( QInputMethodEvent* event );
539
QVariant simulateInputMethodQuery( Qt::InputMethodQuery query ) const;
540
bool simulateEvent( QEvent * ev);
541
void simulateResizeEvent(int width, int height);
546
* Emitted when the user presses a key whilst the terminal widget has focus.
548
void keyPressedSignal(QKeyEvent *e);
551
* A mouse event occurred.
552
* @param button The mouse button (0 for left button, 1 for middle button, 2 for right button, 3 for release)
553
* @param column The character column where the event occurred
554
* @param line The character row where the event occurred
555
* @param eventType The type of event. 0 for a mouse press / release or 1 for mouse motion
557
void mouseSignal(int button, int column, int line, int eventType);
558
void changedFontMetricSignal(int height, int width);
559
void changedContentSizeSignal(int height, int width);
562
* Emitted when the user right clicks on the display, or right-clicks with the Shift
563
* key held down if usesMouse() is true.
565
* This can be used to display a context menu.
567
void configureRequest(const QPoint& position);
570
* When a shortcut which is also a valid terminal key sequence is pressed while
571
* the terminal widget has focus, this signal is emitted to allow the host to decide
572
* whether the shortcut should be overridden.
573
* When the shortcut is overridden, the key sequence will be sent to the terminal emulation instead
574
* and the action associated with the shortcut will not be triggered.
576
* @p override is set to false by default and the shortcut will be triggered as normal.
578
void overrideShortcutCheck(QKeyEvent* keyEvent,bool& override);
580
void isBusySelecting(bool);
581
void sendStringToEmu(const char*);
583
// qtermwidget signals
584
void copyAvailable(bool);
586
void termLostFocus();
588
void notifyBell(const QString&);
590
// QMLTermWidget signals
591
void imageUpdated(QRect);
594
virtual bool event( QEvent * );
596
virtual void paintEvent( QPaintEvent * );
598
virtual void showEvent(QShowEvent*);
599
virtual void hideEvent(QHideEvent*);
600
virtual void resizeEvent(QResizeEvent*);
602
virtual void fontChange(const QFont &font);
603
virtual void focusInEvent(QFocusEvent* event);
604
virtual void focusOutEvent(QFocusEvent* event);
605
virtual void keyPressEvent(QKeyEvent* event);
606
virtual void mouseDoubleClickEvent(QMouseEvent* ev);
607
virtual void mousePressEvent( QMouseEvent* );
608
virtual void mouseReleaseEvent( QMouseEvent* );
609
virtual void mouseMoveEvent( QMouseEvent* );
610
virtual void extendSelection( const QPoint& pos );
611
virtual void wheelEvent( QWheelEvent* );
613
virtual bool focusNextPrevChild( bool next );
616
virtual void dragEnterEvent(QDragEnterEvent* event);
617
virtual void dropEvent(QDropEvent* event);
619
enum DragState { diNone, diPending, diDragging };
627
// classifies the 'ch' into one of three categories
628
// and returns a character to indicate which category it is in
630
// - A space (returns ' ')
631
// - Part of a word (returns 'a')
632
// - Other characters (returns the input character)
633
QChar charClass(QChar ch) const;
637
void mouseTripleClickEvent(QMouseEvent* ev);
640
virtual void inputMethodEvent ( QInputMethodEvent* event );
641
virtual QVariant inputMethodQuery( Qt::InputMethodQuery query ) const;
645
void scrollBarPositionChanged(int value);
647
void blinkCursorEvent();
649
//Renables bell noises and visuals. Used to disable further bells for a short period of time
650
//after emitting the first in a sequence of bell events.
655
void swapColorTable();
656
void tripleClickTimeout(); // resets possibleTripleClick
660
// -- Drawing helpers --
662
// divides the part of the display specified by 'rect' into
663
// fragments according to their colors and styles and calls
664
// drawTextFragment() to draw the fragments
665
void drawContents(QPainter &paint, const QRect &rect);
666
// draws a section of text, all the text in this section
667
// has a common color and style
668
void drawTextFragment(QPainter& painter, const QRect& rect,
669
const QString& text, const Character* style);
670
// draws the background for a text fragment
671
// if useOpacitySetting is true then the color's alpha value will be set to
672
// the display's transparency (set with setOpacity()), otherwise the background
673
// will be drawn fully opaque
674
void drawBackground(QPainter& painter, const QRect& rect, const QColor& color,
675
bool useOpacitySetting);
676
// draws the cursor character
677
void drawCursor(QPainter& painter, const QRect& rect , const QColor& foregroundColor,
678
const QColor& backgroundColor , bool& invertColors);
679
// draws the characters or line graphics in a text fragment
680
void drawCharacters(QPainter& painter, const QRect& rect, const QString& text,
681
const Character* style, bool invertCharacterColor);
682
// draws a string of line graphics
683
void drawLineCharString(QPainter& painter, int x, int y,
684
const QString& str, const Character* attributes);
686
// draws the preedit string for input methods
687
void drawInputMethodPreeditString(QPainter& painter , const QRect& rect);
691
// maps an area in the character image to an area on the widget
692
QRect imageToWidget(const QRect& imageArea) const;
694
// the area where the preedit string for input methods will be draw
695
QRect preeditRect() const;
697
// shows a notification window in the middle of the widget indicating the terminal's
698
// current size in columns and lines
699
void showResizeNotification();
701
// scrolls the image by a number of lines.
702
// 'lines' may be positive ( to scroll the image down )
703
// or negative ( to scroll the image up )
704
// 'region' is the part of the image to scroll - currently only
705
// the top, bottom and height of 'region' are taken into account,
706
// the left and right are ignored.
707
void scrollImage(int lines , const QRect& region);
710
void propagateSize();
711
void updateImageSize();
714
void paintFilters(QPainter& painter);
716
// returns a region covering all of the areas of the widget which contain
718
QRegion hotSpotRegion() const;
720
// returns the position of the cursor in columns and lines
721
QPoint cursorPosition() const;
723
// redraws the cursor
726
bool handleShortcutOverrideEvent(QKeyEvent* event);
728
// the window onto the terminal screen which this display
729
// is currently showing.
730
QPointer<ScreenWindow> _screenWindow;
734
QGridLayout* _gridLayout;
736
bool _fixedFont; // has fixed pitch
737
int _fontHeight; // height
738
int _fontWidth; // width
739
int _fontAscent; // ascend
740
bool _boldIntense; // Whether intense colors should be rendered with bold font
742
int _leftMargin; // offset
743
int _topMargin; // offset
745
int _lines; // the number of lines that can be displayed in the widget
746
int _columns; // the number of columns that can be displayed in the widget
748
int _usedLines; // the number of lines that are actually being used, this will be less
749
// than 'lines' if the character image provided with setImage() is smaller
750
// than the maximum image size which can be displayed
752
int _usedColumns; // the number of columns that are actually being used, this will be less
753
// than 'columns' if the character image provided with setImage() is smaller
754
// than the maximum image size which can be displayed
758
Character* _image; // [lines][columns]
759
// only the area [usedLines][usedColumns] in the image contains valid data
762
QVector<LineProperty> _lineProperties;
764
ColorEntry _colorTable[TABLE_COLORS];
768
bool _terminalSizeHint;
769
bool _terminalSizeStartup;
773
QPoint _iPntSel; // initial selection point
774
QPoint _pntSel; // current selection point
775
QPoint _tripleSelBegin; // help avoid flicker
776
int _actSel; // selection state
777
bool _wordSelectionMode;
778
bool _lineSelectionMode;
779
bool _preserveLineBreaks;
780
bool _columnSelectionMode;
782
QClipboard* _clipboard;
783
QScrollBar* _scrollBar;
784
ScrollBarPosition _scrollbarLocation;
785
QString _wordCharacters;
788
bool _blinking; // hide text in paintEvent
789
bool _hasBlinker; // has characters to blink
790
bool _cursorBlinking; // hide cursor in paintEvent
791
bool _hasBlinkingCursor; // has blinking cursor enabled
792
bool _allowBlinkingText; // allow text to blink
793
bool _ctrlDrag; // require Ctrl key for drag
794
TripleClickMode _tripleClickMode;
795
bool _isFixedSize; //Columns / lines are locked.
796
QTimer* _blinkTimer; // active when hasBlinker
797
QTimer* _blinkCursorTimer; // active when hasBlinkingCursor
803
bool _possibleTripleClick; // is set in mouseDoubleClickEvent and deleted
804
// after QApplication::doubleClickInterval() delay
807
QLabel* _resizeWidget;
808
QTimer* _resizeTimer;
810
bool _flowControlWarningEnabled;
812
//widgets related to the warning message that appears when the user presses Ctrl+S to suspend
813
//terminal output - informing them what has happened and how to resume output
814
QLabel* _outputSuspendedLabel;
818
bool _colorsInverted; // true during visual bell
824
// list of filters currently applied to the display. used for links and
826
TerminalImageFilterChain* _filterChain;
827
QRegion _mouseOverHotspotArea;
829
KeyboardCursorShape _cursorShape;
831
// custom cursor color. if this is invalid then the foreground
832
// color of the character under the cursor is used
836
MotionAfterPasting mMotionAfterPasting;
838
struct InputMethodData
840
QString preeditString;
841
QRect previousPreeditRect;
843
InputMethodData _inputMethodData;
845
static bool _antialiasText; // do we antialias or not
847
//the delay in milliseconds between redrawing blinking text
848
static const int TEXT_BLINK_DELAY = 500;
849
static const int DEFAULT_LEFT_MARGIN = 1;
850
static const int DEFAULT_TOP_MARGIN = 1;
853
static void setTransparencyEnabled(bool enable)
855
HAVE_TRANSPARENCY = enable;
859
class AutoScrollHandler : public QObject
864
AutoScrollHandler(QWidget* parent);
866
virtual void timerEvent(QTimerEvent* event);
867
virtual bool eventFilter(QObject* watched,QEvent* event);
869
QWidget* widget() const { return static_cast<QWidget*>(parent()); }
875
#endif // TERMINALDISPLAY_H