1 /*
2     Copyright (C) 2007, 2013 by Robert Knight <robertknight@gmail.com>
3 
4     Rewritten for QT4 by e_k <e_k at users.sourceforge.net>, Copyright (C)2008
5 
6     This program is free software: you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10 
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15 
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19     02110-1301  USA.
20 */
21 
22 #ifndef SCREENWINDOW_H
23 #define SCREENWINDOW_H
24 
25 // Qt
26 #include <QtCore/QObject>
27 #include <QtCore/QPoint>
28 #include <QtCore/QRect>
29 
30 // Konsole
31 #include "unix/Character.h"
32 
33 class Screen;
34 
35 /**
36  * Provides a window onto a section of a terminal screen.
37  * This window can then be rendered by a terminal display widget ( TerminalDisplay ).
38  *
39  * To use the screen window, create a new ScreenWindow() instance and associated it with
40  * a terminal screen using setScreen().
41  * Use the scrollTo() method to scroll the window up and down on the screen.
42  * Call the getImage() method to retrieve the character image which is currently visible in the window.
43  *
44  * setTrackOutput() controls whether the window moves to the bottom of the associated screen when new
45  * lines are added to it.
46  *
47  * Whenever the output from the underlying screen is changed, the notifyOutputChanged() slot should
48  * be called.  This in turn will update the window's position and emit the outputChanged() signal
49  * if necessary.
50  */
51 class ScreenWindow : public QObject
52 {
53 Q_OBJECT
54 
55 public:
56     /**
57      * Constructs a new screen window with the given parent.
58      * A screen must be specified by calling setScreen() before calling getImage() or getLineProperties().
59      *
60      * You should not call this constructor directly, instead use the Emulation::createWindow() method
61      * to create a window on the emulation which you wish to view.  This allows the emulation
62      * to notify the window when the associated screen has changed and synchronize selection updates
63      * between all views on a session.
64      */
65     ScreenWindow(QObject* parent = nullptr);
66 	virtual ~ScreenWindow();
67 
68     /** Sets the screen which this window looks onto */
69     void setScreen(Screen* screen);
70     /** Returns the screen which this window looks onto */
71     Screen* screen() const;
72 
73     /**
74      * Returns the image of characters which are currently visible through this window
75      * onto the screen.
76      *
77      * The buffer is managed by the ScreenWindow instance and does not need to be
78      * deleted by the caller.
79      */
80     Character* getImage();
81 
82     /**
83      * Returns the line attributes associated with the lines of characters which
84      * are currently visible through this window
85      */
86     QVector<LineProperty> getLineProperties();
87 
88     /**
89      * Returns the number of lines which the region of the window
90      * specified by scrollRegion() has been scrolled by since the last call
91      * to resetScrollCount().  scrollRegion() is in most cases the
92      * whole window, but will be a smaller area in, for example, applications
93      * which provide split-screen facilities.
94      *
95      * This is not guaranteed to be accurate, but allows views to optimise
96      * rendering by reducing the amount of costly text rendering that
97      * needs to be done when the output is scrolled.
98      */
99     int scrollCount() const;
100 
101     /**
102      * Resets the count of scrolled lines returned by scrollCount()
103      */
104     void resetScrollCount();
105 
106     /**
107      * Returns the area of the window which was last scrolled, this is
108      * usually the whole window area.
109      *
110      * Like scrollCount(), this is not guaranteed to be accurate,
111      * but allows views to optimise rendering.
112      */
113     QRect scrollRegion() const;
114 
115     /**
116      * Sets the start of the selection to the given @p line and @p column within
117      * the window.
118      */
119     void setSelectionStart( int column , int line , bool columnMode );
120     /**
121      * Sets the end of the selection to the given @p line and @p column within
122      * the window.
123      */
124     void setSelectionEnd( int column , int line );
125     /**
126      * Retrieves the start of the selection within the window.
127      */
128     void getSelectionStart( int& column , int& line );
129     /**
130      * Retrieves the end of the selection within the window.
131      */
132     void getSelectionEnd( int& column , int& line );
133     /**
134      * Returns true if the character at @p line , @p column is part of the selection.
135      */
136     bool isSelected( int column , int line );
137     /**
138      * Clears the current selection
139      */
140     void clearSelection();
141 
142 	/** Sets the number of lines in the window */
143 	void setWindowLines(int lines);
144     /** Returns the number of lines in the window */
145     int windowLines() const;
146     /** Returns the number of columns in the window */
147     int windowColumns() const;
148 
149     /** Returns the total number of lines in the screen */
150     int lineCount() const;
151     /** Returns the total number of columns in the screen */
152     int columnCount() const;
153 
154     /** Returns the index of the line which is currently at the top of this window */
155     int currentLine() const;
156 
157     /**
158      * Returns the position of the cursor
159      * within the window.
160      */
161     QPoint cursorPosition() const;
162 
163     /**
164      * Convenience method. Returns true if the window is currently at the bottom
165      * of the screen.
166      */
167     bool atEndOfOutput() const;
168 
169     /** Scrolls the window so that @p line is at the top of the window */
170     void scrollTo( int line );
171 
172     enum RelativeScrollMode
173     {
174         ScrollLines,
175         ScrollPages
176     };
177 
178     /**
179      * Scrolls the window relative to its current position on the screen.
180      *
181      * @param mode Specifies whether @p amount refers to the number of lines or the number
182      * of pages to scroll.
183      * @param amount The number of lines or pages ( depending on @p mode ) to scroll by.  If
184      * this number is positive, the view is scrolled down.  If this number is negative, the view
185      * is scrolled up.
186      */
187     void scrollBy( RelativeScrollMode mode , int amount );
188 
189     /**
190      * Specifies whether the window should automatically move to the bottom
191      * of the screen when new output is added.
192      *
193      * If this is set to true, the window will be moved to the bottom of the associated screen ( see
194      * screen() ) when the notifyOutputChanged() method is called.
195      */
196     void setTrackOutput(bool trackOutput);
197     /**
198      * Returns whether the window automatically moves to the bottom of the screen as
199      * new output is added.  See setTrackOutput()
200      */
201     bool trackOutput() const;
202 
203     /**
204      * Returns the text which is currently selected.
205      *
206      * @param preserveLineBreaks See Screen::selectedText()
207      */
208     QString selectedText( bool preserveLineBreaks ) const;
209 
210 public slots:
211     /**
212      * Notifies the window that the contents of the associated terminal screen have changed.
213      * This moves the window to the bottom of the screen if trackOutput() is true and causes
214      * the outputChanged() signal to be emitted.
215      */
216     void notifyOutputChanged();
217 
218 signals:
219     /**
220      * Emitted when the contents of the associated terminal screen ( see screen() ) changes.
221      */
222     void outputChanged();
223 
224     /**
225      * Emitted when the screen window is scrolled to a different position.
226      *
227      * @param line The line which is now at the top of the window.
228      */
229     void scrolled(int line);
230 
231     /**
232      * Emitted when the selection is changed.
233      */
234     void selectionChanged();
235 
236 private:
237 	int endWindowLine() const;
238 	void fillUnusedArea();
239 
240     Screen* _screen; // see setScreen() , screen()
241 	Character* _windowBuffer;
242 	int _windowBufferSize;
243 	bool _bufferNeedsUpdate;
244 
245 	int  _windowLines;
246     int  _currentLine; // see scrollTo() , currentLine()
247     bool _trackOutput; // see setTrackOutput() , trackOutput()
248     int  _scrollCount; // count of lines which the window has been scrolled by since
249                        // the last call to resetScrollCount()
250 };
251 
252 #endif // SCREENWINDOW_H
253