diff --git a/src/Screen.cpp b/src/Screen.cpp index 10aec4cdf..63b990e0b 100644 --- a/src/Screen.cpp +++ b/src/Screen.cpp @@ -857,11 +857,17 @@ void Screen::scrollUp(int n) \sa setRegion \sa scrollDown */ +QRect Screen::lastScrolledRegion() const +{ + return _lastScrolledRegion; +} + void Screen::scrollUp(int from, int n) { if (n <= 0 || from + n > bmargin) return; _scrolledLines -= n; + _lastScrolledRegion = QRect(0,tmargin,columns-1,(bmargin-tmargin)); //qDebug() << "Screen::scrollUp( from: " << from << " , n: " << n << ")"; @@ -1402,7 +1408,8 @@ void Screen::copyLineToStream(int line , int start, int count, QTextStream* stream, TerminalCharacterDecoder* decoder) { //buffer to hold characters for decoding - //the buffer is static to avoid initialising every element on each call to copyLineToStream + //the buffer is static to avoid initialising every + //element on each call to copyLineToStream //(which is unnecessary since all elements will be overwritten anyway) static const int MAX_CHARS = 1024; static Character characterBuffer[MAX_CHARS]; diff --git a/src/Screen.h b/src/Screen.h index 075fef173..8bf548dfb 100644 --- a/src/Screen.h +++ b/src/Screen.h @@ -24,6 +24,7 @@ #define SCREEN_H // Qt +#include #include #include @@ -330,6 +331,15 @@ public: // these are all `Screen' operations * a negative return value indicates that the image has been scrolled down. */ int scrolledLines() const; + + /** + * Returns the region of the image which was last scrolled. + * + * This is the area of the image from the top margin to the + * bottom margin when the last scroll occurred. + */ + QRect lastScrolledRegion() const; + /** * Resets the count of the number of lines that the image has been scrolled up or down by, * see scrolledLines() @@ -388,6 +398,7 @@ private: // helper ImageLine* screenLines; // [lines] int _scrolledLines; + QRect _lastScrolledRegion; QVarLengthArray lineProperties; diff --git a/src/ScreenWindow.cpp b/src/ScreenWindow.cpp index 5e83c07db..f29323640 100644 --- a/src/ScreenWindow.cpp +++ b/src/ScreenWindow.cpp @@ -196,6 +196,11 @@ void ScreenWindow::resetScrollCount() _scrollCount = 0; } +QRect ScreenWindow::scrollRegion() const +{ + return _screen->lastScrolledRegion(); +} + void ScreenWindow::notifyOutputChanged() { // move window to the bottom of the screen and update scroll count diff --git a/src/ScreenWindow.h b/src/ScreenWindow.h index f299797b4..6a6c239c7 100644 --- a/src/ScreenWindow.h +++ b/src/ScreenWindow.h @@ -23,6 +23,7 @@ // Qt #include #include +#include // Konsole #include "TECommon.h" @@ -87,9 +88,15 @@ public: QVector getLineProperties(); /** - * Returns the number of lines which the window has been scrolled by since the last - * call to resetScrollCount(). - * This allows views to optimise scrolling operations. + * Returns the number of lines which the region of the window + * specified by scrollRegion() has been scrolled by since the last call + * to resetScrollCount(). scrollRegion() is in most cases the + * whole window, but will be a smaller area in, for example, applications + * which provide split-screen facilities. + * + * This is not guaranteed to be accurate, but allows views to optimise + * rendering by reducing the amount of costly text rendering that + * needs to be done when the output is scrolled. */ int scrollCount() const; @@ -98,6 +105,15 @@ public: */ void resetScrollCount(); + /** + * Returns the area of the window which was last scrolled, this is + * usually the whole window area. + * + * Like scrollCount(), this is not guaranteed to be accurate, + * but allows views to optimise rendering. + */ + QRect scrollRegion() const; + /** * Sets the start of the selection to the given @p line and @p column within * the window. diff --git a/src/SessionController.cpp b/src/SessionController.cpp index 563a61fd9..69f8c671e 100644 --- a/src/SessionController.cpp +++ b/src/SessionController.cpp @@ -429,7 +429,7 @@ void SessionController::setupActions() action->setShortcut( QKeySequence(Qt::CTRL+Qt::SHIFT+Qt::Key_Minus) ); connect( action , SIGNAL(triggered()) , this , SLOT(decreaseTextSize()) ); - // History + // Scrollback _searchToggleAction = new KAction(i18n("Search Output..."),this); _searchToggleAction->setShortcut( QKeySequence(Qt::CTRL+Qt::SHIFT+Qt::Key_F) ); _searchToggleAction->setIcon( KIcon("edit-find") ); @@ -469,6 +469,11 @@ void SessionController::setupActions() action->setShortcut( QKeySequence(Qt::CTRL+Qt::SHIFT+Qt::Key_X) ); connect( action , SIGNAL(triggered()) , this , SLOT(clearHistoryAndReset()) ); + // Menu + action = collection->addAction("show-menubar"); + action->setText( i18n("Show Menubar") ); + connect( action , SIGNAL(toggled(bool)) , this , SIGNAL(showMenuBarToggle(bool)) ); + // Profile Options action = collection->addAction("edit-current-profile"); action->setText( i18n("Edit Current Profile...") ); diff --git a/src/TECommon.h b/src/TECommon.h index 419e63891..c1e4a5f11 100644 --- a/src/TECommon.h +++ b/src/TECommon.h @@ -1,5 +1,7 @@ /* This file is part of Konsole, an X terminal. + + Copyright (C) 2007 by Robert Knight Copyright (C) 1997,1998 by Lars Doelle This program is free software; you can redistribute it and/or modify @@ -44,18 +46,21 @@ typedef unsigned short UINT16; /*! */ -struct ColorEntry +class ColorEntry { +public: ColorEntry(QColor c, bool tr, bool b) : color(c), transparent(tr), bold(b) {} ColorEntry() : transparent(false), bold(false) {} // default constructors - void operator=(const ColorEntry& rhs) { + + void operator=(const ColorEntry& rhs) + { color = rhs.color; transparent = rhs.transparent; bold = rhs.bold; } QColor color; - bool transparent; // if used on bg - bool bold; // if used on fg + bool transparent; // applies if color is used in background + bool bold; // applies if color is used in foreground }; @@ -184,53 +189,67 @@ static const int LINE_DOUBLEHEIGHT = (1 << 2); class CharacterColor { + friend class Character; + public: - CharacterColor() : t(0), u(0), v(0), w(0) {} - CharacterColor(UINT8 ty, int co) : t(ty), u(0), v(0), w(0) + CharacterColor() + : _colorSpace(COLOR_SPACE_UNDEFINED), + _u(0), + _v(0), + _w(0) + {} + + CharacterColor(UINT8 colorSpace, int co) + : _colorSpace(colorSpace), + _u(0), + _v(0), + _w(0) { - if (COLOR_SPACE_DEFAULT == t) { - u = co & 1; - } else if (COLOR_SPACE_SYSTEM == t) { - u = co & 7; - v = (co >> 3) & 1; - } else if (COLOR_SPACE_256 == t) { - u = co & 255; - } else if (COLOR_SPACE_RGB == t) { - u = co >> 16; - v = co >> 8; - w = co; - } -#if 0 - // Doesn't work with gcc 3.3.4 - switch (t) + switch (colorSpace) { - case COLOR_SPACE_UNDEFINED: break; - case COLOR_SPACE_DEFAULT: u = co& 1; break; - case COLOR_SPACE_SYSTEM: u = co& 7; v = (co>>3)&1; break; - case COLOR_SPACE_256: u = co&255; break; - case COLOR_SPACE_RGB: u = co>>16; v = co>>8; w = co; break; - default : t = 0; break; + case COLOR_SPACE_DEFAULT: + _u = co & 1; + break; + case COLOR_SPACE_SYSTEM: + _u = co & 7; + _v = (co >> 3) & 1; + break; + case COLOR_SPACE_256: + _u = co & 255; + break; + case COLOR_SPACE_RGB: + _u = co >> 16; + _v = co >> 8; + _w = co; + break; } -#endif } - UINT8 t; // color space indicator - UINT8 u; // various bytes representing the data in the respective ... - UINT8 v; // ... color space. C++ does not do unions, so we cannot ... - UINT8 w; // ... express ourselfs here, properly. + void toggleIntensive(); // Hack or helper? QColor color(const ColorEntry* base) const; + friend bool operator == (const CharacterColor& a, const CharacterColor& b); friend bool operator != (const CharacterColor& a, const CharacterColor& b); + +private: + UINT8 _colorSpace; + + // bytes storing the character color + UINT8 _u; + UINT8 _v; + UINT8 _w; }; inline bool operator == (const CharacterColor& a, const CharacterColor& b) { - return *reinterpret_cast(&a.t) == *reinterpret_cast(&b.t); + return *reinterpret_cast(&a._colorSpace) == + *reinterpret_cast(&b._colorSpace); } inline bool operator != (const CharacterColor& a, const CharacterColor& b) { - return *reinterpret_cast(&a.t) != *reinterpret_cast(&b.t); + return *reinterpret_cast(&a._colorSpace) != + *reinterpret_cast(&b._colorSpace); } inline const QColor color256(UINT8 u, const ColorEntry* base) @@ -250,21 +269,24 @@ inline const QColor color256(UINT8 u, const ColorEntry* base) inline QColor CharacterColor::color(const ColorEntry* base) const { - switch (t) + switch (_colorSpace) { - case COLOR_SPACE_DEFAULT: return base[u+0+(v?BASE_COLORS:0)].color; - case COLOR_SPACE_SYSTEM: return base[u+2+(v?BASE_COLORS:0)].color; - case COLOR_SPACE_256: return color256(u,base); - case COLOR_SPACE_RGB: return QColor(u,v,w); - default : return QColor(255,0,0); // diagnostic catch all + case COLOR_SPACE_DEFAULT: return base[_u+0+(_v?BASE_COLORS:0)].color; + case COLOR_SPACE_SYSTEM: return base[_u+2+(_v?BASE_COLORS:0)].color; + case COLOR_SPACE_256: return color256(_u,base); + case COLOR_SPACE_RGB: return QColor(_u,_v,_w); } + + Q_ASSERT(false); // invalid color space; + + return QColor(); } inline void CharacterColor::toggleIntensive() { - if (t == COLOR_SPACE_SYSTEM || t == COLOR_SPACE_DEFAULT) + if (_colorSpace == COLOR_SPACE_SYSTEM || _colorSpace == COLOR_SPACE_DEFAULT) { - v = !v; + _v = !_v; } } @@ -320,18 +342,18 @@ inline bool operator != (const Character& a, const Character& b) inline bool Character::isTransparent(const ColorEntry* base) const { - return ((backgroundColor.t == COLOR_SPACE_DEFAULT) && - base[backgroundColor.u+0+(backgroundColor.v?BASE_COLORS:0)].transparent) - || ((backgroundColor.t == COLOR_SPACE_SYSTEM) && - base[backgroundColor.u+2+(backgroundColor.v?BASE_COLORS:0)].transparent); + return ((backgroundColor._colorSpace == COLOR_SPACE_DEFAULT) && + base[backgroundColor._u+0+(backgroundColor._v?BASE_COLORS:0)].transparent) + || ((backgroundColor._colorSpace == COLOR_SPACE_SYSTEM) && + base[backgroundColor._u+2+(backgroundColor._v?BASE_COLORS:0)].transparent); } inline bool Character::isBold(const ColorEntry* base) const { - return (backgroundColor.t == COLOR_SPACE_DEFAULT) && - base[backgroundColor.u+0+(backgroundColor.v?BASE_COLORS:0)].bold - || (backgroundColor.t == COLOR_SPACE_SYSTEM) && - base[backgroundColor.u+2+(backgroundColor.v?BASE_COLORS:0)].bold; + return (backgroundColor._colorSpace == COLOR_SPACE_DEFAULT) && + base[backgroundColor._u+0+(backgroundColor._v?BASE_COLORS:0)].bold + || (backgroundColor._colorSpace == COLOR_SPACE_SYSTEM) && + base[backgroundColor._u+2+(backgroundColor._v?BASE_COLORS:0)].bold; } extern unsigned short vt100_graphics[32]; diff --git a/src/TerminalDisplay.cpp b/src/TerminalDisplay.cpp index 70dcc6769..1cb5dfb04 100644 --- a/src/TerminalDisplay.cpp +++ b/src/TerminalDisplay.cpp @@ -693,64 +693,73 @@ void TerminalDisplay::setCursorPos(const int curx, const int cury) _cursorCol = curx; } -// scrolls the _image by '_lines', down if _lines > 0 or up otherwise. +// scrolls the image by 'lines', down if lines > 0 or up otherwise. // // the terminal emulation keeps track of the scrolling of the character -// _image as it receives input, and when the view is updated, it calls scrollImage() +// image as it receives input, and when the view is updated, it calls scrollImage() // with the final scroll amount. this improves performance because scrolling the -// display is much cheaper than re-rendering all the text for the part -// of the _image which has moved up or down. instead only new _lines have to be drawn +// display is much cheaper than re-rendering all the text for the +// part of the image which has moved up or down. +// Instead only new lines have to be drawn // -// note: it is important that the area of the display which is scrolled aligns properly with -// the character grid - which has a top left point at (_bX,_bY) , +// note: it is important that the area of the display which is +// scrolled aligns properly with the character grid - +// which has a top left point at (_bX,_bY) , // a cell width of _fontWidth and a cell height of _fontHeight). -void TerminalDisplay::scrollImage(int _lines) +void TerminalDisplay::scrollImage(int lines , const QRect& region) { - if ( _lines == 0 || _image == 0 || abs(_lines) >= this->_usedLines ) return; + if ( lines == 0 || _image == 0 || abs(lines) >= region.height() ) return; QRect scrollRect; + //qDebug() << "Scrolled region: top =" << region.top() + // << ", bottom =" << region.bottom() + // << ", height =" << region.height() << "lines. Image height =" + // << this->_usedLines << "lines" + // << ", scroll =" << lines << "lines"; + + void* firstCharPos = &_image[ region.top() * this->_usedColumns ]; + void* lastCharPos = &_image[ (region.top() + abs(lines)) * this->_usedColumns ]; + + int top = _bY + (region.top() * _fontHeight); + int linesToMove = region.height() - abs(lines); + int bytesToMove = linesToMove * + this->_usedColumns * + sizeof(Character); + + Q_ASSERT( linesToMove > 0 ); + Q_ASSERT( bytesToMove > 0 ); + //scroll internal _image - if ( _lines > 0 ) + if ( lines > 0 ) { - assert( (_lines*this->_usedColumns) < _imageSize ); + assert( (lines*this->_usedColumns) < _imageSize ); //scroll internal _image down - memmove( _image , &_image[_lines*this->_usedColumns] , - ( this->_usedLines - _lines ) * - this->_usedColumns * - sizeof(Character) ); - + memmove( firstCharPos , lastCharPos , bytesToMove ); + //set region of display to scroll, making sure that //the region aligns correctly to the character grid - scrollRect = QRect( _bX ,_bY, + scrollRect = QRect( _bX , top, this->_usedColumns * _fontWidth , - (this->_usedLines - _lines) * _fontHeight ); - - //qDebug() << "scrolled down " << _lines << " _lines"; + linesToMove * _fontHeight ); } else { //scroll internal _image up - memmove( &_image[ abs(_lines)*this->_usedColumns] , _image , - (this->_usedLines - abs(_lines) ) * - this->_usedColumns * - sizeof(Character) ); - + memmove( lastCharPos , firstCharPos , bytesToMove ); + //set region of the display to scroll, making sure that //the region aligns correctly to the character grid - - QPoint topPoint( _bX , _bY + abs(_lines)*_fontHeight ); + QPoint topPoint( _bX , top + abs(lines)*_fontHeight ); - scrollRect = QRect( topPoint , + scrollRect = QRect( topPoint , QSize( this->_usedColumns*_fontWidth , - (this->_usedLines - abs(_lines)) * _fontHeight )); - - //qDebug() << "scrolled up " << _lines << " _lines"; + linesToMove * _fontHeight )); } //scroll the display vertically to match internal _image - scroll( 0 , _fontHeight * (-_lines) , scrollRect ); + scroll( 0 , _fontHeight * (-lines) , scrollRect ); } void TerminalDisplay::processFilters() @@ -772,10 +781,11 @@ void TerminalDisplay::updateImage() if ( !_screenWindow ) return; - // optimization - scroll the existing _image where possible and - // avoid expensive text drawing for parts of the _image that + // optimization - scroll the existing image where possible and + // avoid expensive text drawing for parts of the image that // can simply be moved up or down - scrollImage( _screenWindow->scrollCount() ); + scrollImage( _screenWindow->scrollCount() , + _screenWindow->scrollRegion() ); _screenWindow->resetScrollCount(); Character* const newimg = _screenWindow->getImage(); @@ -954,7 +964,7 @@ void TerminalDisplay::updateImage() // free the image from the screen window delete[] newimg; - // debugging - display a count of the number of _lines that will need + // debugging - display a count of the number of lines that will need // to be repainted //qDebug() << "dirty line count = " << dirtyLineCount; diff --git a/src/TerminalDisplay.h b/src/TerminalDisplay.h index 4d3e7659f..7b514d071 100644 --- a/src/TerminalDisplay.h +++ b/src/TerminalDisplay.h @@ -565,9 +565,13 @@ private: // shows the popup menu associated with a hotspot void showHotSpotMenu(Filter::HotSpot* spot , const QPoint& position); - // scrolls the image by a number of lines. 'lines' may be positive ( to scroll the image down ) + // scrolls the image by a number of lines. + // 'lines' may be positive ( to scroll the image down ) // or negative ( to scroll the image up ) - void scrollImage(int lines); + // 'region' is the part of the image to scroll - currently only + // the top, bottom and height of 'region' are taken into account, + // the left and right are ignored. + void scrollImage(int lines , const QRect& region); void calcGeometry(); void propagateSize(); diff --git a/src/ViewProperties.cpp b/src/ViewProperties.cpp index d9e4a9ec8..e67a03359 100644 --- a/src/ViewProperties.cpp +++ b/src/ViewProperties.cpp @@ -29,27 +29,6 @@ ViewProperties::ViewProperties(QObject* parent) { } -#if 0 -void ViewProperties::setFlag(ViewFlag flag , bool set) -{ - if ( set && !(_flags & flag) ) - { - _flags |= flag; - emit flagsChanged(this); - } - else if ( !set && (_flags & flag) ) - { - _flags &= ~flag; - emit flagsChanged(this); - } -} - -ViewProperties::ViewFlag ViewProperties::flags() const -{ - return (ViewFlag)_flags; -} -#endif - KUrl ViewProperties::url() const { return KUrl(); diff --git a/src/ViewProperties.h b/src/ViewProperties.h index dcf72735a..78bd0dbdd 100644 --- a/src/ViewProperties.h +++ b/src/ViewProperties.h @@ -65,46 +65,11 @@ public: */ int identifier() const; -#if 0 - /** - * This enum describes the flags which provide information - * about the current state of the view. - */ - enum ViewFlag - { - /** - * Specifies that activity (often this means additional output) - * has occurred in the view. - */ - ActivityFlag = 1 - }; - - /** Returns view's current flags. */ - ViewFlag flags() const; - - /** - * Sets or clears the specified view flag. - * - * @param flag The flag to set or clear. - * @param set True to set the flag or false to clear it. - */ - void setFlag(ViewFlag flag , bool set = true); - - /** - * Convenience method. Unsets the specified flag. - * Equivalent to calling setFlag(@p flag,false); - */ - void clearFlag(ViewFlag flag) { setFlag(flag,false); } -#endif - signals: /** Emitted when the icon for a view changes */ void iconChanged(ViewProperties* properties); /** Emitted when the title for a view changes */ void titleChanged(ViewProperties* properties); - ///** Emitted when the flags associated with a view change. */ - //void flagsChanged(ViewProperties* properties); - /** Emitted when activity has occurred in this view. */ void activity(ViewProperties* item);