2
Copyright (C) 2007 by Robert Knight <robertknight@gmail.com>
3
Copyright (C) 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
5
Rewritten for QT4 by e_k <e_k at users.sourceforge.net>, Copyright (C)2008
7
This program is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 2 of the License, or
10
(at your option) any later version.
12
This program is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
GNU General Public License for more details.
17
You should have received a copy of the GNU General Public License
18
along with this program; if not, write to the Free Software
19
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23
#ifndef TERMINALDISPLAY_H
24
#define TERMINALDISPLAY_H
27
#include <QtGui/QColor>
28
#include <QtCore/QPointer>
29
#include <QtGui/QWidget>
33
#include "Character.h"
34
#include "ColorTables.h"
37
class QDragEnterEvent;
55
extern unsigned short vt100_graphics[32];
60
* A widget which displays output from a terminal emulation and sends input keypresses and mouse activity
63
* When the terminal emulation receives new output from the program running in the terminal,
64
* it will update the display by calling updateImage().
66
* TODO More documentation
68
class TerminalDisplay : public QWidget
73
/** Constructs a new terminal display widget with the specified parent. */
74
TerminalDisplay( QWidget *parent = 0 );
75
virtual ~TerminalDisplay();
77
/** Returns the terminal color palette used by the display. */
78
const ColorEntry* colorTable() const;
79
/** Sets the terminal color palette used by the display. */
80
void setColorTable( const ColorEntry table[] );
82
* Sets the seed used to generate random colors for the display
83
* (in color schemes that support them).
85
void setRandomSeed( uint seed );
87
* Returns the seed used to generate random colors for the display
88
* (in color schemes that support them).
90
uint randomSeed() const;
92
/** Sets the opacity of the terminal display. */
93
void setOpacity( qreal opacity );
96
* This enum describes the location where the scroll bar is positioned in the display widget.
98
enum ScrollBarPosition
100
/** Do not show the scroll bar. */
102
/** Show the scroll bar on the left side of the display. */
104
/** Show the scroll bar on the right side of the display. */
108
* Specifies whether the terminal display has a vertical scroll bar, and if so whether it
109
* is shown on the left or right side of the display.
111
void setScrollBarPosition( ScrollBarPosition position );
114
* Sets the current position and range of the display's scroll bar.
116
* @param cursor The position of the scroll bar's thumb.
117
* @param lines The maximum value of the scroll bar.
119
void setScroll( int cursor, int lines );
122
* Returns the display's filter chain. When the image for the display is updated,
123
* the text is passed through each filter in the chain. Each filter can define
124
* hotspots which correspond to certain strings (such as URLs or particular words).
125
* Depending on the type of the hotspots created by the filter ( returned by Filter::Hotspot::type() )
126
* the view will draw visual cues such as underlines on mouse-over for links or translucent
127
* rectangles for markers.
129
* To add a new filter to the view, call:
130
* viewWidget->filterChain()->addFilter( filterObject );
132
FilterChain* filterChain() const;
135
* Updates the filters in the display's filter chain. This will cause
136
* the hotspots to be updated to match the current image.
138
* WARNING: This function can be expensive depending on the
139
* image size and number of filters in the filterChain()
141
* TODO - This API does not really allow efficient usage. Revise it so
142
* that the processing can be done in a better way.
145
* - Area of interest may be known ( eg. mouse cursor hovering
148
void processFilters();
151
* Returns a list of menu actions created by the filters for the content
152
* at the given @p position.
154
QList<QAction*> filterActions( const QPoint& position );
156
/** Returns true if the cursor is set to blink or false otherwise. */
157
bool blinkingCursor() { return _hasBlinkingCursor; }
158
/** Specifies whether or not the cursor blinks. */
159
void setBlinkingCursor( bool blink );
161
void setCtrlDrag( bool enable ) { _ctrlDrag = enable; }
162
bool ctrlDrag() { return _ctrlDrag; }
165
* This enum describes the methods for selecting text when
166
* the user triple-clicks within the display.
170
/** Select the whole line underneath the cursor. */
172
/** Select from the current cursor position to the end of the line. */
173
SelectForwardsFromCursor
175
/** Sets how the text is selected when the user triple clicks within the display. */
176
void setTripleClickMode( TripleClickMode mode ) { _tripleClickMode = mode; }
177
/** See setTripleClickSelectionMode() */
178
TripleClickMode tripleClickMode() { return _tripleClickMode; }
180
void setLineSpacing( uint );
181
uint lineSpacing() const;
183
void emitSelection( bool useXselection, bool appendReturn );
186
* This enum describes the available shapes for the keyboard cursor.
187
* See setKeyboardCursorShape()
189
enum KeyboardCursorShape
191
/** A rectangular block which covers the entire area of the cursor character. */
194
* A single flat line which occupies the space at the bottom of the cursor
199
* An cursor shaped like the capital letter 'I', similar to the IBeam
200
* cursor used in Qt/KDE text editors.
205
* Sets the shape of the keyboard cursor. This is the cursor drawn
206
* at the position in the terminal where keyboard input will appear.
208
* In addition the terminal display widget also has a cursor for
209
* the mouse pointer, which can be set using the QWidget::setCursor()
212
* Defaults to BlockCursor
214
void setKeyboardCursorShape( KeyboardCursorShape shape );
216
* Returns the shape of the keyboard cursor. See setKeyboardCursorShape()
218
KeyboardCursorShape keyboardCursorShape() const;
221
* Sets the color used to draw the keyboard cursor.
223
* The keyboard cursor defaults to using the foreground color of the character
226
* @param useForegroundColor If true, the cursor color will change to match
227
* the foreground color of the character underneath it as it is moved, in this
228
* case, the @p color parameter is ignored and the color of the character
229
* under the cursor is inverted to ensure that it is still readable.
230
* @param color The color to use to draw the cursor. This is only taken into
231
* account if @p useForegroundColor is false.
233
void setKeyboardCursorColor( bool useForegroundColor , const QColor& color );
236
* Returns the color of the keyboard cursor, or an invalid color if the keyboard
237
* cursor color is set to change according to the foreground color of the character
240
QColor keyboardCursorColor() const;
243
* Returns the number of lines of text which can be displayed in the widget.
245
* This will depend upon the height of the widget and the current font.
248
int lines() { return _lines; }
250
* Returns the number of characters of text which can be displayed on
251
* each line in the widget.
253
* This will depend upon the width of the widget and the current font.
256
int columns() { return _columns; }
259
* Returns the height of the characters in the font used to draw the text in the display.
261
int fontHeight() { return _fontHeight; }
263
* Returns the width of the characters in the display.
264
* This assumes the use of a fixed-width font.
266
int fontWidth() { return _fontWidth; }
268
void setSize( int cols, int lins );
269
void setFixedSize( int cols, int lins );
272
QSize sizeHint() const;
275
* Sets which characters, in addition to letters and numbers,
276
* are regarded as being part of a word for the purposes
277
* of selecting words in the display by double clicking on them.
279
* The word boundaries occur at the first and last characters which
280
* are either a letter, number, or a character in @p wc
282
* @param wc An array of characters which are to be considered parts
283
* of a word ( in addition to letters and numbers ).
285
void setWordCharacters( const QString& wc );
287
* Returns the characters which are considered part of a word for the
288
* purpose of selecting words in the display with the mouse.
290
* @see setWordCharacters()
292
QString wordCharacters() { return _wordCharacters; }
295
* Sets the type of effect used to alert the user when a 'bell' occurs in the
298
* The terminal session can trigger the bell effect by calling bell() with
301
void setBellMode( int mode );
303
* Returns the type of effect used to alert the user when a 'bell' occurs in
304
* the terminal session.
308
int bellMode() { return _bellMode; }
311
* This enum describes the different types of sounds and visual effects which
312
* can be used to alert the user when a 'bell' occurs in the terminal
317
/** A system beep. */
320
* KDE notification. This may play a sound, show a passive popup
321
* or perform some other action depending on the user's settings.
324
/** A silent, visual bell (eg. inverting the display's colors briefly) */
326
/** No bell effects */
330
void setSelection( const QString &t );
333
* Reimplemented. Has no effect. Use setVTFont() to change the font
334
* used to draw characters in the display.
336
virtual void setFont( const QFont & );
338
/** Returns the font used to draw characters in the display */
339
QFont getVTFont() { return font(); }
342
* Sets the font used to draw the display. Has no effect if @p font
343
* is larger than the size of the display itself.
345
void setVTFont( const QFont& font );
348
* Specified whether anti-aliasing of text in the terminal display
349
* is enabled or not. Defaults to enabled.
351
static void setAntialias( bool antialias ) { _antialiasText = antialias; }
353
* Returns true if anti-aliasing of text in the terminal is enabled.
355
static bool antialias() { return _antialiasText; }
358
* Sets whether or not the current height and width of the
359
* terminal in lines and columns is displayed whilst the widget
362
void setTerminalSizeHint( bool on ) { _terminalSizeHint = on; }
364
* Returns whether or not the current height and width of
365
* the terminal in lines and columns is displayed whilst the widget
368
bool terminalSizeHint() { return _terminalSizeHint; }
370
* Sets whether the terminal size display is shown briefly
371
* after the widget is first shown.
373
* See setTerminalSizeHint() , isTerminalSizeHint()
375
void setTerminalSizeStartup( bool on ) { _terminalSizeStartup = on; }
377
void setBidiEnabled( bool set ) { _bidiEnabled = set; }
378
bool isBidiEnabled() { return _bidiEnabled; }
381
* Sets the terminal screen section which is displayed in this widget.
382
* When updateImage() is called, the display fetches the latest character image from the
383
* the associated terminal screen window.
385
* In terms of the model-view paradigm, the ScreenWindow is the model which is rendered
386
* by the TerminalDisplay.
388
void setScreenWindow( ScreenWindow* window );
389
/** Returns the terminal screen section which is displayed in this widget. See setScreenWindow() */
390
ScreenWindow* screenWindow() const;
392
static bool HAVE_TRANSPARENCY;
397
* Causes the terminal display to fetch the latest character image from the associated
398
* terminal screen ( see setScreenWindow() ) and redraw the display.
402
* Causes the terminal display to fetch the latest line status flags from the
403
* associated terminal screen ( see setScreenWindow() ).
405
void updateLineProperties();
407
/** Copies the selected text to the clipboard. */
408
void copyClipboard();
410
* Pastes the content of the clipboard into the
413
void pasteClipboard();
415
* Pastes the content of the selection into the
418
void pasteSelection();
421
* Changes whether the flow control warning box should be shown when the flow control
422
* stop key (Ctrl+S) are pressed.
424
void setFlowControlWarningEnabled( bool enabled );
427
* Causes the widget to display or hide a message informing the user that terminal
428
* output has been suspended (by using the flow control key combination Ctrl+S)
430
* @param suspended True if terminal output has been suspended and the warning message should
431
* be shown or false to indicate that terminal output has been resumed and that
432
* the warning message should disappear.
434
void outputSuspended( bool suspended );
437
* Sets whether the program whoose output is being displayed in the view
438
* is interested in mouse events.
440
* If this is set to true, mouse signals will be emitted by the view when the user clicks, drags
441
* or otherwise moves the mouse inside the view.
442
* The user interaction needed to create selections will also change, and the user will be required
443
* to hold down the shift key to create a selection or perform other mouse activities inside the
444
* view area - since the program running in the terminal is being allowed to handle normal mouse
447
* @param usesMouse Set to true if the program running in the terminal is interested in mouse events
448
* or false otherwise.
450
void setUsesMouse( bool usesMouse );
452
/** See setUsesMouse() */
453
bool usesMouse() const;
456
* Shows a notification that a bell event has occurred in the terminal.
457
* TODO: More documentation here
459
void bell( const QString& message );
464
* Emitted when the user presses a key whilst the terminal widget has focus.
466
void keyPressedSignal( QKeyEvent *e );
469
* Emitted when the user presses the suspend or resume flow control key combinations
471
* @param suspend true if the user pressed Ctrl+S (the suspend output key combination) or
472
* false if the user pressed Ctrl+Q (the resume output key combination)
474
void flowControlKeyPressed( bool suspend );
477
* A mouse event occurred.
478
* @param button The mouse button (0 for left button, 1 for middle button, 2 for right button, 3 for release)
479
* @param column The character column where the event occurred
480
* @param line The character row where the event occurred
481
* @param eventType The type of event. 0 for a mouse press / release or 1 for mouse motion
483
void mouseSignal( int button, int column, int line, int eventType );
484
void changedFontMetricSignal( int height, int width );
485
void changedContentSizeSignal( int height, int width );
488
* Emitted when the user right clicks on the display, or right-clicks with the Shift
489
* key held down if usesMouse() is true.
491
* This can be used to display a context menu.
493
void configureRequest( TerminalDisplay*, int state, const QPoint& position );
495
void isBusySelecting( bool );
496
void sendStringToEmu( const char* );
499
virtual bool event( QEvent * );
501
virtual void paintEvent( QPaintEvent * );
503
virtual void showEvent( QShowEvent* );
504
virtual void hideEvent( QHideEvent* );
505
virtual void resizeEvent( QResizeEvent* );
507
virtual void fontChange( const QFont &font );
509
virtual void keyPressEvent( QKeyEvent* event );
510
virtual void mouseDoubleClickEvent( QMouseEvent* ev );
511
virtual void mousePressEvent( QMouseEvent* );
512
virtual void mouseReleaseEvent( QMouseEvent* );
513
virtual void mouseMoveEvent( QMouseEvent* );
514
virtual void extendSelection( const QPoint& pos );
515
virtual void wheelEvent( QWheelEvent* );
517
virtual bool focusNextPrevChild( bool next );
520
virtual void dragEnterEvent( QDragEnterEvent* event );
521
virtual void dropEvent( QDropEvent* event );
523
enum DragState { diNone, diPending, diDragging };
532
virtual int charClass( quint16 ) const;
536
void mouseTripleClickEvent( QMouseEvent* ev );
539
virtual void inputMethodEvent( QInputMethodEvent* event );
540
virtual QVariant inputMethodQuery( Qt::InputMethodQuery query ) const;
544
void scrollBarPositionChanged( int value );
546
void blinkCursorEvent();
548
//Renables bell noises and visuals. Used to disable further bells for a short period of time
549
//after emitting the first in a sequence of bell events.
554
void swapColorTable();
555
void tripleClickTimeout(); // resets possibleTripleClick
559
// -- Drawing helpers --
561
// divides the part of the display specified by 'rect' into
562
// fragments according to their colors and styles and calls
563
// drawTextFragment() to draw the fragments
564
void drawContents( QPainter &paint, const QRect &rect );
565
// draws a section of text, all the text in this section
566
// has a common color and style
567
void drawTextFragment( QPainter& painter, const QRect& rect,
568
const QString& text, const Character* style );
569
// draws the background for a text fragment
570
// if useOpacitySetting is true then the color's alpha value will be set to
571
// the display's transparency (set with setOpacity()), otherwise the background
572
// will be drawn fully opaque
573
void drawBackground( QPainter& painter, const QRect& rect, const QColor& color,
574
bool useOpacitySetting );
575
// draws the cursor character
576
void drawCursor( QPainter& painter, const QRect& rect , const QColor& foregroundColor,
577
const QColor& backgroundColor , bool& invertColors );
578
// draws the characters or line graphics in a text fragment
579
void drawCharacters( QPainter& painter, const QRect& rect, const QString& text,
580
const Character* style, bool invertCharacterColor );
581
// draws a string of line graphics
582
void drawLineCharString( QPainter& painter, int x, int y,
583
const QString& str, const Character* attributes );
585
// draws the preedit string for input methods
586
void drawInputMethodPreeditString( QPainter& painter , const QRect& rect );
590
// maps an area in the character image to an area on the widget
591
QRect imageToWidget( const QRect& imageArea ) const;
593
// maps a point on the widget to the position ( ie. line and column )
594
// of the character at that point.
595
void getCharacterPosition( const QPoint& widgetPoint, int& line, int& column ) const;
597
// the area where the preedit string for input methods will be draw
598
QRect preeditRect() const;
600
// shows a notification window in the middle of the widget indicating the terminal's
601
// current size in columns and lines
602
void showResizeNotification();
604
// scrolls the image by a number of lines.
605
// 'lines' may be positive ( to scroll the image down )
606
// or negative ( to scroll the image up )
607
// 'region' is the part of the image to scroll - currently only
608
// the top, bottom and height of 'region' are taken into account,
609
// the left and right are ignored.
610
void scrollImage( int lines , const QRect& region );
613
void propagateSize();
614
void updateImageSize();
617
void paintFilters( QPainter& painter );
619
// returns a region covering all of the areas of the widget which contain
621
QRegion hotSpotRegion() const;
623
// returns the position of the cursor in columns and lines
624
QPoint cursorPosition() const;
626
// the window onto the terminal screen which this display
627
// is currently showing.
628
QPointer<ScreenWindow> _screenWindow;
632
QGridLayout* _gridLayout;
634
bool _fixedFont; // has fixed pitch
635
int _fontHeight; // height
636
int _fontWidth; // width
637
int _fontAscent; // ascend
639
int _leftMargin; // offset
640
int _topMargin; // offset
642
int _lines; // the number of lines that can be displayed in the widget
643
int _columns; // the number of columns that can be displayed in the widget
645
int _usedLines; // the number of lines that are actually being used, this will be less
646
// than 'lines' if the character image provided with setImage() is smaller
647
// than the maximum image size which can be displayed
649
int _usedColumns; // the number of columns that are actually being used, this will be less
650
// than 'columns' if the character image provided with setImage() is smaller
651
// than the maximum image size which can be displayed
655
Character* _image; // [lines][columns]
656
// only the area [usedLines][usedColumns] in the image contains valid data
659
QVector<LineProperty> _lineProperties;
661
ColorEntry _colorTable[TABLE_COLORS];
665
bool _terminalSizeHint;
666
bool _terminalSizeStartup;
670
QPoint _iPntSel; // initial selection point
671
QPoint _pntSel; // current selection point
672
QPoint _tripleSelBegin; // help avoid flicker
673
int _actSel; // selection state
674
bool _wordSelectionMode;
675
bool _lineSelectionMode;
676
bool _preserveLineBreaks;
677
bool _columnSelectionMode;
679
QClipboard* _clipboard;
680
QScrollBar* _scrollBar;
681
ScrollBarPosition _scrollbarLocation;
682
QString _wordCharacters;
685
bool _blinking; // hide text in paintEvent
686
bool _hasBlinker; // has characters to blink
687
bool _cursorBlinking; // hide cursor in paintEvent
688
bool _hasBlinkingCursor; // has blinking cursor enabled
689
bool _ctrlDrag; // require Ctrl key for drag
690
TripleClickMode _tripleClickMode;
691
bool _isFixedSize; //Columns / lines are locked.
692
QTimer* _blinkTimer; // active when hasBlinker
693
QTimer* _blinkCursorTimer; // active when hasBlinkingCursor
699
bool _possibleTripleClick; // is set in mouseDoubleClickEvent and deleted
700
// after QApplication::doubleClickInterval() delay
703
QLabel* _resizeWidget;
704
QTimer* _resizeTimer;
706
bool _flowControlWarningEnabled;
708
//widgets related to the warning message that appears when the user presses Ctrl+S to suspend
709
//terminal output - informing them what has happened and how to resume output
710
QLabel* _outputSuspendedLabel;
714
bool _colorsInverted; // true during visual bell
720
// list of filters currently applied to the display. used for links and
722
TerminalImageFilterChain* _filterChain;
723
QRect _mouseOverHotspotArea;
725
KeyboardCursorShape _cursorShape;
727
// custom cursor color. if this is invalid then the foreground
728
// color of the character under the cursor is used
732
struct InputMethodData
734
QString preeditString;
735
QRect previousPreeditRect;
737
InputMethodData _inputMethodData;
739
static bool _antialiasText; // do we antialias or not
741
//the delay in milliseconds between redrawing blinking text
742
static const int BLINK_DELAY = 500;
743
static const int DEFAULT_LEFT_MARGIN = 1;
744
static const int DEFAULT_TOP_MARGIN = 1;
747
static void setTransparencyEnabled( bool enable )
749
HAVE_TRANSPARENCY = enable;
755
#endif // TERMINALDISPLAY_H