diff options
author | Andreas Loibl <andreas@andreas-loibl.de> | 2011-03-17 05:07:10 +0100 |
---|---|---|
committer | Andreas Loibl <andreas@andreas-loibl.de> | 2011-03-17 05:07:10 +0100 |
commit | 00286a5db286e21a766b6af057052dc5d17561ad (patch) | |
tree | 7232dadf6dc3570705c3104fe0c000f480c7a0ee /qtermwidget/ScreenWindow.cpp | |
download | acritoxinstaller-00286a5db286e21a766b6af057052dc5d17561ad.zip acritoxinstaller-00286a5db286e21a766b6af057052dc5d17561ad.tar.gz |
Initial commit
Diffstat (limited to 'qtermwidget/ScreenWindow.cpp')
-rw-r--r-- | qtermwidget/ScreenWindow.cpp | 296 |
1 files changed, 296 insertions, 0 deletions
diff --git a/qtermwidget/ScreenWindow.cpp b/qtermwidget/ScreenWindow.cpp new file mode 100644 index 0000000..f29dcd0 --- /dev/null +++ b/qtermwidget/ScreenWindow.cpp @@ -0,0 +1,296 @@ +/* + Copyright (C) 2007 by Robert Knight <robertknight@gmail.com> + + Rewritten for QT4 by e_k <e_k at users.sourceforge.net>, Copyright (C)2008 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. +*/ + +// Own +#include "ScreenWindow.h" + +// Qt +#include <QtCore> + +// Konsole +#include "Screen.h" + +using namespace Konsole; + +ScreenWindow::ScreenWindow(QObject* parent) + : QObject(parent) + , _windowBuffer(0) + , _windowBufferSize(0) + , _bufferNeedsUpdate(true) + , _windowLines(1) + , _currentLine(0) + , _trackOutput(true) + , _scrollCount(0) +{ +} +ScreenWindow::~ScreenWindow() +{ + delete[] _windowBuffer; +} +void ScreenWindow::setScreen(Screen* screen) +{ + Q_ASSERT( screen ); + + _screen = screen; +} + +Screen* ScreenWindow::screen() const +{ + return _screen; +} + +Character* ScreenWindow::getImage() +{ + // reallocate internal buffer if the window size has changed + int size = windowLines() * windowColumns(); + if (_windowBuffer == 0 || _windowBufferSize != size) + { + delete[] _windowBuffer; + _windowBufferSize = size; + _windowBuffer = new Character[size]; + _bufferNeedsUpdate = true; + } + + if (!_bufferNeedsUpdate) + return _windowBuffer; + + _screen->getImage(_windowBuffer,size, + currentLine(),endWindowLine()); + + // this window may look beyond the end of the screen, in which + // case there will be an unused area which needs to be filled + // with blank characters + fillUnusedArea(); + + _bufferNeedsUpdate = false; + return _windowBuffer; +} + +void ScreenWindow::fillUnusedArea() +{ + int screenEndLine = _screen->getHistLines() + _screen->getLines() - 1; + int windowEndLine = currentLine() + windowLines() - 1; + + int unusedLines = windowEndLine - screenEndLine; + int charsToFill = unusedLines * windowColumns(); + + Screen::fillWithDefaultChar(_windowBuffer + _windowBufferSize - charsToFill,charsToFill); +} + +// return the index of the line at the end of this window, or if this window +// goes beyond the end of the screen, the index of the line at the end +// of the screen. +// +// when passing a line number to a Screen method, the line number should +// never be more than endWindowLine() +// +int ScreenWindow::endWindowLine() const +{ + return qMin(currentLine() + windowLines() - 1, + lineCount() - 1); +} +QVector<LineProperty> ScreenWindow::getLineProperties() +{ + QVector<LineProperty> result = _screen->getLineProperties(currentLine(),endWindowLine()); + + if (result.count() != windowLines()) + result.resize(windowLines()); + + return result; +} + +QString ScreenWindow::selectedText( bool preserveLineBreaks ) const +{ + return _screen->selectedText( preserveLineBreaks ); +} + +void ScreenWindow::getSelectionStart( int& column , int& line ) +{ + _screen->getSelectionStart(column,line); + line -= currentLine(); +} +void ScreenWindow::getSelectionEnd( int& column , int& line ) +{ + _screen->getSelectionEnd(column,line); + line -= currentLine(); +} +void ScreenWindow::setSelectionStart( int column , int line , bool columnMode ) +{ + _screen->setSelectionStart( column , qMin(line + currentLine(),endWindowLine()) , columnMode); + + _bufferNeedsUpdate = true; + emit selectionChanged(); +} + +void ScreenWindow::setSelectionEnd( int column , int line ) +{ + _screen->setSelectionEnd( column , qMin(line + currentLine(),endWindowLine()) ); + + _bufferNeedsUpdate = true; + emit selectionChanged(); +} + +bool ScreenWindow::isSelected( int column , int line ) +{ + return _screen->isSelected( column , qMin(line + currentLine(),endWindowLine()) ); +} + +void ScreenWindow::clearSelection() +{ + _screen->clearSelection(); + + emit selectionChanged(); +} + +void ScreenWindow::setWindowLines(int lines) +{ + Q_ASSERT(lines > 0); + _windowLines = lines; +} +int ScreenWindow::windowLines() const +{ + return _windowLines; +} + +int ScreenWindow::windowColumns() const +{ + return _screen->getColumns(); +} + +int ScreenWindow::lineCount() const +{ + return _screen->getHistLines() + _screen->getLines(); +} + +int ScreenWindow::columnCount() const +{ + return _screen->getColumns(); +} + +QPoint ScreenWindow::cursorPosition() const +{ + QPoint position; + + position.setX( _screen->getCursorX() ); + position.setY( _screen->getCursorY() ); + + return position; +} + +int ScreenWindow::currentLine() const +{ + return qBound(0,_currentLine,lineCount()-windowLines()); +} + +void ScreenWindow::scrollBy( RelativeScrollMode mode , int amount ) +{ + if ( mode == ScrollLines ) + { + scrollTo( currentLine() + amount ); + } + else if ( mode == ScrollPages ) + { + scrollTo( currentLine() + amount * ( windowLines() / 2 ) ); + } +} + +bool ScreenWindow::atEndOfOutput() const +{ + return currentLine() == (lineCount()-windowLines()); +} + +void ScreenWindow::scrollTo( int line ) +{ + int maxCurrentLineNumber = lineCount() - windowLines(); + line = qBound(0,line,maxCurrentLineNumber); + + const int delta = line - _currentLine; + _currentLine = line; + + // keep track of number of lines scrolled by, + // this can be reset by calling resetScrollCount() + _scrollCount += delta; + + _bufferNeedsUpdate = true; + + emit scrolled(_currentLine); +} + +void ScreenWindow::setTrackOutput(bool trackOutput) +{ + _trackOutput = trackOutput; +} + +bool ScreenWindow::trackOutput() const +{ + return _trackOutput; +} + +int ScreenWindow::scrollCount() const +{ + return _scrollCount; +} + +void ScreenWindow::resetScrollCount() +{ + _scrollCount = 0; +} + +QRect ScreenWindow::scrollRegion() const +{ + bool equalToScreenSize = windowLines() == _screen->getLines(); + + if ( atEndOfOutput() && equalToScreenSize ) + return _screen->lastScrolledRegion(); + else + return QRect(0,0,windowColumns(),windowLines()); +} + +void ScreenWindow::notifyOutputChanged() +{ + // move window to the bottom of the screen and update scroll count + // if this window is currently tracking the bottom of the screen + if ( _trackOutput ) + { + _scrollCount -= _screen->scrolledLines(); + _currentLine = qMax(0,_screen->getHistLines() - (windowLines()-_screen->getLines())); + } + else + { + // if the history is not unlimited then it may + // have run out of space and dropped the oldest + // lines of output - in this case the screen + // window's current line number will need to + // be adjusted - otherwise the output will scroll + _currentLine = qMax(0,_currentLine - + _screen->droppedLines()); + + // ensure that the screen window's current position does + // not go beyond the bottom of the screen + _currentLine = qMin( _currentLine , _screen->getHistLines() ); + } + + _bufferNeedsUpdate = true; + + emit outputChanged(); +} + +//#include "moc_ScreenWindow.cpp" |