File indexing completed on 2024-04-21 05:51:27

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