File indexing completed on 2024-05-19 05:28:18

0001 /*
0002     SPDX-FileCopyrightText: 2007-2008 Robert Knight <robertknight@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 
0006     This program is distributed in the hope that it will be useful,
0007     but WITHOUT ANY WARRANTY; without even the implied warranty of
0008     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0009     GNU General Public License for more details.
0010 
0011     You should have received a copy of the GNU General Public License
0012     along with this program; if not, write to the Free Software
0013     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
0014     02110-1301  USA.
0015 */
0016 
0017 #ifndef SCREENWINDOW_H
0018 #define SCREENWINDOW_H
0019 
0020 // Qt
0021 #include <QObject>
0022 #include <QPoint>
0023 #include <QRect>
0024 
0025 // Konsole
0026 #include "Character.h"
0027 #include "KeyboardTranslator.h"
0028 
0029 namespace Konsole
0030 {
0031 
0032 class Screen;
0033 
0034 /**
0035  * Provides a window onto a section of a terminal screen.  A terminal widget can then render
0036  * the contents of the window and use the window to change the terminal screen's selection
0037  * in response to mouse or keyboard input.
0038  *
0039  * A new ScreenWindow for a terminal session can be created by calling Emulation::createWindow()
0040  *
0041  * Use the scrollTo() method to scroll the window up and down on the screen.
0042  * Use the getImage() method to retrieve the character image which is currently visible in the window.
0043  *
0044  * setTrackOutput() controls whether the window moves to the bottom of the associated screen when new
0045  * lines are added to it.
0046  *
0047  * Whenever the output from the underlying screen is changed, the notifyOutputChanged() slot should
0048  * be called.  This in turn will update the window's position and Q_EMIT the outputChanged() signal
0049  * if necessary.
0050  */
0051 class ScreenWindow : public QObject
0052 {
0053     Q_OBJECT
0054 
0055 public:
0056     /**
0057      * Constructs a new screen window with the given parent.
0058      * A screen must be specified by calling setScreen() before calling getImage() or getLineProperties().
0059      *
0060      * You should not call this constructor directly, instead use the Emulation::createWindow() method
0061      * to create a window on the emulation which you wish to view.  This allows the emulation
0062      * to notify the window when the associated screen has changed and synchronize selection updates
0063      * between all views on a session.
0064      */
0065     ScreenWindow(QObject *parent = nullptr);
0066     ~ScreenWindow() override;
0067 
0068     /** Sets the screen which this window looks onto */
0069     void setScreen(Screen *screen);
0070     /** Returns the screen which this window looks onto */
0071     Screen *screen() const;
0072 
0073     /**
0074      * Returns the image of characters which are currently visible through this window
0075      * onto the screen.
0076      *
0077      * The returned buffer is managed by the ScreenWindow instance and does not need to be
0078      * deleted by the caller.
0079      */
0080     std::span<Character> getImage();
0081 
0082     /**
0083      * Returns the line attributes associated with the lines of characters which
0084      * are currently visible through this window
0085      */
0086     QVector<LineProperty> getLineProperties();
0087 
0088     /**
0089      * Returns the number of lines which the region of the window
0090      * specified by scrollRegion() has been scrolled by since the last call
0091      * to resetScrollCount().  scrollRegion() is in most cases the
0092      * whole window, but will be a smaller area in, for example, applications
0093      * which provide split-screen facilities.
0094      *
0095      * This is not guaranteed to be accurate, but allows views to optimize
0096      * rendering by reducing the amount of costly text rendering that
0097      * needs to be done when the output is scrolled.
0098      */
0099     int scrollCount() const;
0100 
0101     /**
0102      * Resets the count of scrolled lines returned by scrollCount()
0103      */
0104     void resetScrollCount();
0105 
0106     /**
0107      * Returns the area of the window which was last scrolled, this is
0108      * usually the whole window area.
0109      *
0110      * Like scrollCount(), this is not guaranteed to be accurate,
0111      * but allows views to optimize rendering.
0112      */
0113     QRect scrollRegion() const;
0114 
0115     /**
0116      * Sets the start of the selection to the given @p line and @p column within
0117      * the window.
0118      */
0119     void setSelectionStart(int column, int line, bool columnMode);
0120     /**
0121      * Sets the end of the selection to the given @p line and @p column within
0122      * the window.
0123      */
0124     void setSelectionEnd(int column, int line);
0125     /**
0126      * Retrieves the start of the selection within the window.
0127      */
0128     void getSelectionStart(int &column, int &line);
0129     /**
0130      * Retrieves the end of the selection within the window.
0131      */
0132     void getSelectionEnd(int &column, int &line);
0133     /**
0134      * Returns true if the character at @p line , @p column is part of the selection.
0135      */
0136     bool isSelected(int column, int line);
0137     /**
0138      * Clears the current selection
0139      */
0140     void clearSelection();
0141 
0142     /** Sets the number of lines in the window */
0143     void setWindowLines(int lines);
0144     /** Returns the number of lines in the window */
0145     int windowLines() const;
0146     /** Returns the number of columns in the window */
0147     int windowColumns() const;
0148 
0149     /** Returns the total number of lines in the screen */
0150     int lineCount() const;
0151     /** Returns the total number of columns in the screen */
0152     int columnCount() const;
0153 
0154     /** Returns the index of the line which is currently at the top of this window */
0155     int currentLine() const;
0156 
0157     /**
0158      * Returns the position of the cursor
0159      * within the window.
0160      */
0161     QPoint cursorPosition() const;
0162 
0163     /**
0164      * Convenience method. Returns true if the window is currently at the bottom
0165      * of the screen.
0166      */
0167     bool atEndOfOutput() const;
0168 
0169     /** Scrolls the window so that @p line is at the top of the window */
0170     void scrollTo(int line);
0171 
0172     /** Describes the units which scrollBy() moves the window by. */
0173     enum RelativeScrollMode {
0174         /** Scroll the window down by a given number of lines. */
0175         ScrollLines,
0176         /**
0177          * Scroll the window down by a given number of pages, where
0178          * one page is windowLines() lines
0179          */
0180         ScrollPages
0181     };
0182 
0183     /**
0184      * Scrolls the window relative to its current position on the screen.
0185      *
0186      * @param mode Specifies whether @p amount refers to the number of lines or the number
0187      * of pages to scroll.
0188      * @param amount The number of lines or pages ( depending on @p mode ) to scroll by.  If
0189      * this number is positive, the view is scrolled down.  If this number is negative, the view
0190      * is scrolled up.
0191      */
0192     void scrollBy(RelativeScrollMode mode, int amount);
0193 
0194     /**
0195      * Specifies whether the window should automatically move to the bottom
0196      * of the screen when new output is added.
0197      *
0198      * If this is set to true, the window will be moved to the bottom of the associated screen ( see
0199      * screen() ) when the notifyOutputChanged() method is called.
0200      */
0201     void setTrackOutput(bool trackOutput);
0202     /**
0203      * Returns whether the window automatically moves to the bottom of the screen as
0204      * new output is added.  See setTrackOutput()
0205      */
0206     bool trackOutput() const;
0207 
0208     /**
0209      * Returns the text which is currently selected.
0210      *
0211      * @param preserveLineBreaks See Screen::selectedText()
0212      */
0213     QString selectedText(bool preserveLineBreaks) const;
0214 
0215 public Q_SLOTS:
0216     /**
0217      * Notifies the window that the contents of the associated terminal screen have changed.
0218      * This moves the window to the bottom of the screen if trackOutput() is true and causes
0219      * the outputChanged() signal to be emitted.
0220      */
0221     void notifyOutputChanged();
0222 
0223     void handleCommandFromKeyboard(KeyboardTranslator::Command command);
0224 
0225 Q_SIGNALS:
0226     /**
0227      * Emitted when the contents of the associated terminal screen (see screen()) changes.
0228      */
0229     void outputChanged();
0230 
0231     /**
0232      * Emitted when the screen window is scrolled to a different position.
0233      *
0234      * @param line The line which is now at the top of the window.
0235      */
0236     void scrolled(int line);
0237 
0238     /** Emitted when the selection is changed. */
0239     void selectionChanged();
0240 
0241     void scrollToEnd();
0242 
0243 private:
0244     int endWindowLine() const;
0245     void fillUnusedArea();
0246 
0247     // not owned by us
0248     Screen *_screen; // see setScreen() , screen()
0249     std::vector<Character> _windowBuffer;
0250     int _windowBufferSize;
0251     bool _bufferNeedsUpdate;
0252 
0253     int _windowLines;
0254     int _currentLine; // see scrollTo() , currentLine()
0255     bool _trackOutput; // see setTrackOutput() , trackOutput()
0256     int _scrollCount; // count of lines which the window has been scrolled by since
0257                       // the last call to resetScrollCount()
0258 };
0259 
0260 }
0261 #endif // SCREENWINDOW_H