# HG changeset patch
# User Stefan Miereis <stefan.miereis@gmx.de>
# Date 1427276329 -3600
#      Wed Mar 25 10:38:49 2015 +0100
# Node ID 574546339a9bf9dc6ba61d53bbecc49790f64e2a
# Parent  9a8be23d2c0556011b09fc1ce217f06a715c2ebd
Added horizontal scroll bar for linux systems (Bug #41842)

diff -r 9a8be23d2c05 -r 574546339a9b libgui/qterminal/libqterminal/unix/Screen.cpp
--- a/libgui/qterminal/libqterminal/unix/Screen.cpp	Tue Mar 24 21:07:51 2015 +0100
+++ b/libgui/qterminal/libqterminal/unix/Screen.cpp	Wed Mar 25 10:38:49 2015 +0100
@@ -67,6 +67,8 @@
 Screen::Screen(int l, int c)
   : lines(l),
     columns(c),
+    maxCharsInLine(1),
+    currentCharsInLine(0),
     screenLines(new ImageLine[lines+1] ),
     _scrolledLines(0),
     _droppedLines(0),
@@ -241,6 +243,7 @@
 {
   if (n == 0) n = 1; // Default
   int p = qMax(0,qMin(cuX+n-1,columns-1));
+  currentCharsInLine = qMax(0, currentCharsInLine - n );
   clearImage(loc(cuX,cuY),loc(p,cuY),' ');
 }
 
@@ -263,6 +266,8 @@
   Q_ASSERT( cuX+n < screenLines[cuY].count() );
 
   screenLines[cuY].remove(cuX,n);
+
+  currentCharsInLine = qMax( 0, currentCharsInLine - n );
 }
 
 void Screen::insertChars(int n)
@@ -275,7 +280,8 @@
   screenLines[cuY].insert(cuX,n,' ');
 
   if ( screenLines[cuY].count() > columns )
-      screenLines[cuY].resize(columns);
+    screenLines[cuY].resize(columns);
+  currentCharsInLine = qMax( currentCharsInLine, screenLines[cuY].size() );
 }
 
 void Screen::deleteLines(int n)
@@ -509,7 +515,7 @@
 
 */
 
-void Screen::copyFromHistory(Character* dest, int startLine, int count) const
+void Screen::copyFromHistory(Character* dest, int startLine, int count, int startColumn) const
 {
   Q_ASSERT( startLine >= 0 && count > 0 && startLine + count <= hist->getLines() );
 
@@ -518,7 +524,7 @@
     const int length = qMin(columns,hist->getLineLen(line));
     const int destLineOffset  = (line-startLine)*columns;
 
-    hist->getCells(line,0,length,dest + destLineOffset);
+    hist->getCells(line,startColumn,length,dest + destLineOffset);
 
     for (int column = length; column < columns; column++)
 		dest[destLineOffset+column] = defaultChar;
@@ -529,42 +535,42 @@
     	for (int column = 0; column < columns; column++)
     	{
         	if (isSelected(column,line))
-			{
+                  {
           		reverseRendition(dest[destLineOffset + column]);
-    		}
+                  }
   		}
 	}
   }
 }
 
-void Screen::copyFromScreen(Character* dest , int startLine , int count) const
+void Screen::copyFromScreen(Character* dest , int startLine , int count, int startColumn) const
 {
 	Q_ASSERT( startLine >= 0 && count > 0 && startLine + count <= lines );
 
     for (int line = startLine; line < (startLine+count) ; line++)
     {
        int srcLineStartIndex  = line*columns;
-	   int destLineStartIndex = (line-startLine)*columns;
+       int destLineStartIndex = (line-startLine)*columns;
 
-       for (int column = 0; column < columns; column++)
-       {
-		 int srcIndex = srcLineStartIndex + column;
-		 int destIndex = destLineStartIndex + column;
+       for (int column = startColumn; column < columns + startColumn; column++)
+         {
+           int srcIndex = srcLineStartIndex + column;
+           int destIndex = destLineStartIndex + column - startColumn;
 
-         dest[destIndex] = screenLines[srcIndex/columns].value(srcIndex%columns,defaultChar);
+           dest[destIndex] = screenLines[line].value(column,defaultChar);
 
 	     // invert selected text
-         if (sel_begin != -1 && isSelected(column,line + hist->getLines()))
-           reverseRendition(dest[destIndex]);
-       }
-
+           if (sel_begin != -1 && isSelected(column,line + hist->getLines()))
+             reverseRendition(dest[destIndex]);
+         }
     }
 }
 
-void Screen::getImage( Character* dest, int size, int startLine, int endLine ) const
+void Screen::getImage( Character* dest, int size, int startLine, int endLine, int startColumn ) const
 {
   Q_ASSERT( startLine >= 0 );
   Q_ASSERT( endLine >= startLine && endLine < hist->getLines() + lines );
+  Q_ASSERT( startColumn >=0 );
 
   const int mergedLines = endLine - startLine + 1;
 
@@ -576,15 +582,16 @@
 
   // copy lines from history buffer
   if (linesInHistoryBuffer > 0) {
-  	copyFromHistory(dest,startLine,linesInHistoryBuffer);
-    }
+    copyFromHistory(dest,startLine,linesInHistoryBuffer, startColumn);
+  }
 
   // copy lines from screen buffer
   if (linesInScreenBuffer > 0) {
-  	copyFromScreen(dest + linesInHistoryBuffer*columns,
-				   startLine + linesInHistoryBuffer - hist->getLines(),
-				   linesInScreenBuffer);
-    }				
+    copyFromScreen(dest + linesInHistoryBuffer*columns,
+                   startLine + linesInHistoryBuffer - hist->getLines(),
+                   linesInScreenBuffer, startColumn
+                   );
+  }
 
   // invert display when in screen mode
   if (getMode(MODE_Screen))
@@ -660,6 +667,7 @@
 
 void Screen::clear()
 {
+  currentCharsInLine=0;
   clearEntireScreen();
   home();
 }
@@ -673,7 +681,10 @@
   if (screenLines[cuY].size() < cuX+1)
           screenLines[cuY].resize(cuX+1);
 
-  if (BS_CLEARS) screenLines[cuY][cuX].character = ' ';
+  if (BS_CLEARS) {
+    screenLines[cuY][cuX].character = ' ';
+    currentCharsInLine = qMax( 0, currentCharsInLine-1 );
+  }
 }
 
 void Screen::Tabulate(int n)
@@ -728,6 +739,9 @@
 
 void Screen::NewLine()
 {
+  maxCharsInLine=qMax( maxCharsInLine, currentCharsInLine );
+  currentCharsInLine=0;
+
   if (getMode(MODE_NewLine)) Return();
   index();
 }
@@ -781,6 +795,7 @@
     if (size < cuX+w)
     {
           screenLines[cuY].resize(cuX+w);
+          currentCharsInLine = qMax(currentCharsInLine,screenLines[cuY].size());
     }
   }
 
diff -r 9a8be23d2c05 -r 574546339a9b libgui/qterminal/libqterminal/unix/Screen.h
--- a/libgui/qterminal/libqterminal/unix/Screen.h	Tue Mar 24 21:07:51 2015 +0100
+++ b/libgui/qterminal/libqterminal/unix/Screen.h	Wed Mar 25 10:38:49 2015 +0100
@@ -362,7 +362,7 @@
      * @param startLine Index of first line to copy
      * @param endLine Index of last line to copy
      */
-    void getImage( Character* dest , int size , int startLine , int endLine ) const;
+  void getImage( Character* dest , int size , int startLine , int endLine, int startColumn ) const;
 
     /**
      * Returns the additional attributes associated with lines in the image.
@@ -379,6 +379,12 @@
     int  getColumns() { return columns; }
     /** Return the number of lines in the history buffer. */
     int  getHistLines ();
+    /** Return the maximum number of characters in a line, excluding
+     * trailing  whitespaces, needed to determine the range of the
+     * horizontal scroll bar
+     */
+  int getMaxLineLength() const
+  { return qMax(maxCharsInLine,currentCharsInLine); }
     /**
      * Sets the type of storage used to keep lines in the history.
      * If @p copyPreviousScroll is true then the contents of the previous
@@ -574,17 +580,20 @@
     bool isSelectionValid() const;
 
 	// copies 'count' lines from the screen buffer into 'dest',
-	// starting from 'startLine', where 0 is the first line in the screen buffer
-	void copyFromScreen(Character* dest, int startLine, int count) const;
+	// starting from 'startLine' and 'startColumn', where 0 is the first line in the screen buffer
+  void copyFromScreen(Character* dest, int startLine, int count, int startColumn) const;
 	// copies 'count' lines from the history buffer into 'dest',
-	// starting from 'startLine', where 0 is the first line in the history
-	void copyFromHistory(Character* dest, int startLine, int count) const;
+	// starting from 'startLine' and 'startColumn', where 0 is the first line in the history
+  void copyFromHistory(Character* dest, int startLine, int count, int startColumn) const;
 
 
     // screen image ----------------
     int lines;
     int columns;
 
+    int maxCharsInLine;
+    int currentCharsInLine;
+
     typedef QVector<Character> ImageLine;      // [0..columns]
     ImageLine*          screenLines;    // [lines]
 
diff -r 9a8be23d2c05 -r 574546339a9b libgui/qterminal/libqterminal/unix/ScreenWindow.cpp
--- a/libgui/qterminal/libqterminal/unix/ScreenWindow.cpp	Tue Mar 24 21:07:51 2015 +0100
+++ b/libgui/qterminal/libqterminal/unix/ScreenWindow.cpp	Wed Mar 25 10:38:49 2015 +0100
@@ -35,6 +35,7 @@
 	, _bufferNeedsUpdate(true)
 	, _windowLines(1)
     , _currentLine(0)
+    , _currentColumn(0)
     , _trackOutput(true)
     , _scrollCount(0)
 {
@@ -72,7 +73,8 @@
 		return _windowBuffer;
 
 	_screen->getImage(_windowBuffer,size,
-					  currentLine(),endWindowLine());
+                          currentLine(),endWindowLine(),
+                          _currentColumn );
 
 	// this window may look beyond the end of the screen, in which
 	// case there will be an unused area which needs to be filled
@@ -109,7 +111,7 @@
 QVector<LineProperty> ScreenWindow::getLineProperties()
 {
     QVector<LineProperty> result = _screen->getLineProperties(currentLine(),endWindowLine());
-	
+
 	if (result.count() != windowLines())
 		result.resize(windowLines());
 
@@ -184,13 +186,16 @@
     return _screen->getColumns();
 }
 
+int ScreenWindow::maxLineLength() const
+{
+  return _screen->getMaxLineLength();
+}
 QPoint ScreenWindow::cursorPosition() const
 {
     QPoint position;
 
     position.setX( _screen->getCursorX() );
     position.setY( _screen->getCursorY() );
-
     return position;
 }
 
@@ -199,6 +204,10 @@
     return qBound(0,_currentLine,lineCount()-windowLines());
 }
 
+int ScreenWindow::currentColumn() const
+{
+  return qBound(0, _currentColumn, maxLineLength()-windowColumns());
+}
 void ScreenWindow::scrollBy( RelativeScrollMode mode , int amount )
 {
     if ( mode == ScrollLines )
@@ -211,6 +220,11 @@
     }
 }
 
+void ScreenWindow::hscrollBy( int amount )
+{
+  hscrollTo( currentColumn() + amount );
+}
+
 bool ScreenWindow::atEndOfOutput() const
 {
     return currentLine() == (lineCount()-windowLines());
@@ -233,6 +247,15 @@
     emit scrolled(_currentLine);
 }
 
+void ScreenWindow::hscrollTo( int column )
+{
+  int maxCurrentColumnNumber = maxLineLength() - windowColumns();
+  column = qBound(0, column, maxCurrentColumnNumber );
+  _currentColumn = column;
+
+  _bufferNeedsUpdate = true;
+}
+
 void ScreenWindow::setTrackOutput(bool trackOutput)
 {
     _trackOutput = trackOutput;
diff -r 9a8be23d2c05 -r 574546339a9b libgui/qterminal/libqterminal/unix/ScreenWindow.h
--- a/libgui/qterminal/libqterminal/unix/ScreenWindow.h	Tue Mar 24 21:07:51 2015 +0100
+++ b/libgui/qterminal/libqterminal/unix/ScreenWindow.h	Wed Mar 25 10:38:49 2015 +0100
@@ -150,10 +150,14 @@
     int lineCount() const;
     /** Returns the total number of columns in the screen */
     int columnCount() const;
+    /** Return the biggest number of characters in a line,
+     *	excepting trailing spaces */
+    int maxLineLength() const;
 
     /** Returns the index of the line which is currently at the top of this window */
     int currentLine() const;
-
+    /** Returns the index of the column which is currently at the leftmost side of this window */
+    int currentColumn() const;
     /**
      * Returns the position of the cursor
      * within the window.
@@ -169,6 +173,10 @@
     /** Scrolls the window so that @p line is at the top of the window */
     void scrollTo( int line );
 
+    /** Scrolls the window so that @p column is at the left of the window */
+  void hscrollTo( int column );
+
+
     enum RelativeScrollMode
     {
         ScrollLines,
@@ -186,6 +194,12 @@
      */
     void scrollBy( RelativeScrollMode mode , int amount );
 
+  /**
+     * Scrolls the window horizontally relative to its current position.
+     * @param amount The number of columns to scroll by. If this number is positive, the view
+     * is scrolled right, else left.
+     */
+  void hscrollBy(int amount);
     /**
      * Specifies whether the window should automatically move to the bottom
      * of the screen when new output is added.
@@ -228,6 +242,11 @@
      */
     void scrolled(int line);
 
+    /** Emitted when the screen window is scrolled horizontally
+     * @param column The column which is now at the leftmost side of the window
+     */
+    void hscrolled(int column);
+
     /**
      * Emitted when the selection is changed.
      */
@@ -244,6 +263,7 @@
 
 	int  _windowLines;
     int  _currentLine; // see scrollTo() , currentLine()
+    int _currentColumn;  //see hscrollTo()
     bool _trackOutput; // see setTrackOutput() , trackOutput()
     int  _scrollCount; // count of lines which the window has been scrolled by since
                        // the last call to resetScrollCount()
diff -r 9a8be23d2c05 -r 574546339a9b libgui/qterminal/libqterminal/unix/TerminalView.cpp
--- a/libgui/qterminal/libqterminal/unix/TerminalView.cpp	Tue Mar 24 21:07:51 2015 +0100
+++ b/libgui/qterminal/libqterminal/unix/TerminalView.cpp	Wed Mar 25 10:38:49 2015 +0100
@@ -119,6 +119,7 @@
 
   // Avoid propagating the palette change to the scroll bar
   _scrollBar->setPalette( QApplication::palette() );
+  _hscrollBar->setPalette( QApplication::palette() );
 
   update();
 }
@@ -259,6 +260,7 @@
   ,_preserveLineBreaks(false)
   ,_columnSelectionMode(false)
   ,_scrollbarLocation(NoScrollBar)
+  ,_showHScrollbar(true)
   ,_wordCharacters(":@-./_~")
   ,_bellMode(SystemBeepBell)
   ,_blinking(false)
@@ -296,6 +298,13 @@
   connect(_scrollBar, SIGNAL(valueChanged(int)), this,
           SLOT(scrollBarPositionChanged(int)));
 
+  //create horizontal scroll bar
+  _hscrollBar = new QScrollBar(Qt::Horizontal, this);
+  setHScroll(0,0);
+  _hscrollBar->setCursor( Qt::ArrowCursor );
+  connect(_hscrollBar, SIGNAL(valueChanged(int)), this,
+          SLOT(hscrollBarPositionChanged(int)));
+
   // setup timers for blinking cursor and text
   _blinkTimer   = new QTimer(this);
   connect(_blinkTimer, SIGNAL(timeout()), this, SLOT(blinkEvent()));
@@ -527,10 +536,17 @@
         QRect();
 
   QRegion contentsRegion = QRegion(rect).subtracted(scrollBarArea);
+
+  QRect hscrollBarArea = _hscrollBar->isVisible() ?
+    rect.intersected(_hscrollBar->geometry()) :
+    QRect();
+
+  contentsRegion = contentsRegion.subtracted(hscrollBarArea);
   QRect contentsRect = contentsRegion.boundingRect();
 
   painter.fillRect(contentsRect, backgroundColor);
   painter.fillRect(scrollBarArea,_scrollBar->palette().background());
+  painter.fillRect(hscrollBarArea,_hscrollBar->palette().background());
 }
 
 void TerminalView::drawCursor(QPainter& painter,
@@ -541,6 +557,11 @@
 {
   QRect cursorRect = rect;
   cursorRect.setHeight(_fontHeight - _lineSpacing - 1);
+  /* The cursor coordinates are defined relative to the screen, if we want to scroll
+   * horizontally we must adjust the cursor coordinates for our window by subtracting
+   * the scrolled distance.
+   */
+  cursorRect.translate( -  _screenWindow->currentColumn() * _fontWidth , 0 );
 
   if (!_cursorBlinking)
     {
@@ -582,7 +603,6 @@
                          cursorRect.top(),
                          cursorRect.left(),
                          cursorRect.bottom());
-
     }
 }
 
@@ -652,8 +672,9 @@
   // this may alter the foreground and background colors
   bool invertCharacterColor = false;
 
-  if ( style->rendition & RE_CURSOR )
+  if ( style->rendition & RE_CURSOR ) {
     drawCursor(painter,rect,foregroundColor,backgroundColor,invertCharacterColor);
+  }
   // draw text
   drawCharacters(painter,rect,text,style,invertCharacterColor);
 
@@ -830,6 +851,8 @@
 
   setScroll( _screenWindow->currentLine() , _screenWindow->lineCount() );
 
+  setHScroll( _screenWindow->currentColumn() , _screenWindow->maxLineLength() );
+
   if (!_image)
     updateImageSize(); // Create _image
 
@@ -1035,7 +1058,6 @@
 
   setBlinkingCursorState(blink);
 }
-
 void TerminalView::setBlinkingCursorState(bool blink)
 {
   if (blink && !_blinkCursorTimer->isActive())
@@ -1385,10 +1407,17 @@
     _cursorBlinking = !_cursorBlinking;
   else
     _cursorBlinking = false;
-
-  QRect cursorRect = imageToWidget( QRect(cursorPosition(),QSize(1,1)) );
-
-  update(cursorRect);
+  QRect cursorRect = QRect(cursorPosition(), QSize(1,1) );
+  cursorRect = imageToWidget( cursorRect );
+  update( cursorRect ); // This call to update() is (mysteriously) needed
+                        // because otherwise the cursor disappears when
+                        // the window is scrolled by more than the width
+                        // of cursorRect
+  cursorRect.translate( - _fontWidth * _screenWindow->currentColumn(), 0 );
+      // Cursor coordinates are relative to the _screen,
+      // so we need to move the cursorRect when the window is
+      // scrolled horizontally
+  update( cursorRect );
 }
 
 /* ------------------------------------------------------------------------- */
@@ -1499,6 +1528,15 @@
   updateImage();
 }
 
+void TerminalView::hscrollBarPositionChanged(int)
+{
+  if ( !_screenWindow )
+    return;
+  _screenWindow->hscrollTo( _hscrollBar->value() );
+
+  updateImage();
+}
+
 void TerminalView::setScroll(int cursor, int slines)
 {
   //qDebug("%s %d setScroll", __FILE__, __LINE__);
@@ -1522,6 +1560,29 @@
   connect(_scrollBar, SIGNAL(valueChanged(int)), this, SLOT(scrollBarPositionChanged(int)));
 }
 
+void TerminalView::setHScroll(int cursor, int scolumns)
+{
+  //qDebug("%s %d setHScroll", __FILE__, __LINE__);
+  // update _hscrollBar if the range or value has changed,
+  // otherwise return
+  //
+  // setting the range or value of a _hscrollBar will always trigger
+  // a repaint, so it should be avoided if it is not necessary
+  if ( _hscrollBar->minimum() == 0                 &&
+       _hscrollBar->maximum() == (scolumns - _columns) &&
+       _hscrollBar->value()   == cursor )
+    {
+      return;
+    }
+
+  disconnect(_hscrollBar, SIGNAL(valueChanged(int)), this, SLOT(hscrollBarPositionChanged(int)));
+  _hscrollBar->setRange(0,scolumns - _columns);
+  _hscrollBar->setSingleStep(1);
+  _hscrollBar->setPageStep(_columns);
+  _hscrollBar->setValue(cursor);
+  connect(_hscrollBar, SIGNAL(valueChanged(int)), this, SLOT(hscrollBarPositionChanged(int)));
+}
+
 void TerminalView::setScrollBarPosition(ScrollBarPosition position)
 {
   if (_scrollbarLocation == position) {
@@ -1540,6 +1601,18 @@
   update();
 }
 
+void TerminalView::setHScrollBar(bool show)
+{
+  if ( !show )
+    _hscrollBar->hide();
+  else
+    _hscrollBar->show();
+  _topMargin = _leftMargin = 1;
+  _showHScrollbar = show;
+  propagateSize();
+  update();
+}
+
 void TerminalView::mousePressEvent(QMouseEvent* ev)
 {
   if ( _possibleTripleClick && (ev->button()==Qt::LeftButton) ) {
@@ -2352,6 +2425,14 @@
           //qDebug("%s %d keydown", __FILE__, __LINE__);
           _screenWindow->scrollBy( ScreenWindow::ScrollLines , 1 );
         }
+      else if ( event->key() == Qt::Key_Right )
+        {
+          _screenWindow->hscrollBy( 1 );
+        }
+      else if ( event->key() == Qt::Key_Left )
+        {
+          _screenWindow->hscrollBy( -1 );
+        }
       else {
           update = false;
         }
@@ -2370,10 +2451,22 @@
     }
 
   _screenWindow->setTrackOutput( true );
-
+  if ( event->key() == Qt::Key_Return ||
+       ( !( event->modifiers() == Qt::ShiftModifier ) &&
+         cursorPosition().x() < _screenWindow->currentColumn() ) ) {
+    _screenWindow->hscrollTo( 0 );
+  }
   _actSel=0; // Key stroke implies a screen update, so TerminalDisplay won't
   // know where the current selection is.
 
+  if ( event->key() == Qt::Key_Left || event->key() == Qt::Key_Backspace )
+    {
+      if (cursorPosition().x() < _screenWindow->currentColumn()+1 )
+        {
+          _screenWindow->hscrollBy( - _screenWindow->windowColumns()/2 );
+          updateImage();
+        }
+    }
   if (_hasBlinkingCursor)
     {
       _blinkCursorTimer->start(BLINK_DELAY);
@@ -2499,6 +2592,19 @@
   _topMargin = DEFAULT_TOP_MARGIN;
   _contentHeight = contentsRect().height() - 2 * DEFAULT_TOP_MARGIN + /* mysterious */ 1;
 
+  _hscrollBar->resize( contentsRect().width()-_scrollBar->width(),
+                       QApplication::style()->pixelMetric(QStyle::PM_ScrollBarExtent)
+                       );
+  _contentHeight = contentsRect().height() - _hscrollBar->height();
+  _hscrollBar->move(contentsRect().bottomLeft() - QPoint(0, _hscrollBar->height()));
+  if ( _columns > _screenWindow->maxLineLength() )
+    {
+      _hscrollBar->hide();
+    }
+  else
+    {
+      _hscrollBar->show();
+    }
   if (!_isFixedSize)
     {
       // ensure that display is always at least one column wide
diff -r 9a8be23d2c05 -r 574546339a9b libgui/qterminal/libqterminal/unix/TerminalView.h
--- a/libgui/qterminal/libqterminal/unix/TerminalView.h	Tue Mar 24 21:07:51 2015 +0100
+++ b/libgui/qterminal/libqterminal/unix/TerminalView.h	Wed Mar 25 10:38:49 2015 +0100
@@ -1,7 +1,7 @@
 /*
     Copyright (C) 2007 by Robert Knight <robertknight@gmail.com>
     Copyright (C) 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
-
+}
     Rewritten for QT4 by e_k <e_k at users.sourceforge.net>, Copyright (C)2008
     Copyright (C) 2012-2015 Jacob Dawid <jacob.dawid@cybercatalyst.com>
 
@@ -86,7 +86,7 @@
 
 
     /**
-     * This enum describes the location where the scroll bar is positioned in the display widget.
+     * This enum describes the location where the vertical scroll bar is positioned in the display widget.
      */
     enum ScrollBarPosition
     {
@@ -102,6 +102,10 @@
      * is shown on the left or right side of the display.
      */
     void setScrollBarPosition(ScrollBarPosition position);
+    /**
+     * Specifies whether the terminal display has a horizontal scroll bar
+     */
+  void setHScrollBar(bool show);
 
     /**
      * Sets the current position and range of the display's scroll bar.
@@ -112,6 +116,14 @@
     void setScroll(int cursor, int lines);
 
     /**
+     * Sets the current position and range of the display's horizontal
+     *  scroll bar.
+     * @param cursor The position of the scroll bar's thumb.
+     * @param columns The maximum value of the scroll bar.
+     */
+    void setHScroll(int cursor, int columns);
+
+    /**
      * Returns the display's filter chain.  When the image for the display is updated,
      * the text is passed through each filter in the chain.  Each filter can define
      * hotspots which correspond to certain strings (such as URLs or particular words).
@@ -536,6 +548,7 @@
 protected slots:
 
     void scrollBarPositionChanged(int value);
+    void hscrollBarPositionChanged(int value);
     void blinkEvent();
     void blinkCursorEvent();
 
@@ -602,6 +615,9 @@
     // the left and right are ignored.
     void scrollImage(int lines , const QRect& region);
 
+    // scrolls the Image horizontally by 'columns'
+    void hscrollImage(int columns , const QRect& region);
+
     void calcGeometry();
     void propagateSize();
     void updateImageSize();
@@ -673,7 +689,9 @@
 
     QClipboard*  _clipboard;
     QScrollBar* _scrollBar;
+    QScrollBar* _hscrollBar;
     ScrollBarPosition _scrollbarLocation;
+    bool _showHScrollbar;
     QString     _wordCharacters;
     int         _bellMode;
 
diff -r 9a8be23d2c05 -r 574546339a9b libgui/src/workspace-view.cc
--- a/libgui/src/workspace-view.cc	Tue Mar 24 21:07:51 2015 +0100
+++ b/libgui/src/workspace-view.cc	Wed Mar 25 10:38:49 2015 +0100
@@ -72,6 +72,11 @@
   view->setAlternatingRowColors (true);
   view_previous_row_count = 0;
 
+  //enable sorting by parameter name
+  view->setSortingEnabled(true);
+  view->sortByColumn(0,Qt::AscendingOrder);
+
+
   // Set an empty widget, so we can assign a layout to it.
   setWidget (new QWidget (this));
 
@@ -102,7 +107,8 @@
   // Initialize column order and width of the workspace
   view->horizontalHeader ()->restoreState (
     settings->value ("workspaceview/column_state").toByteArray ());
-
+  // Make the header clickable to enable sorting
+  view->horizontalHeader ()->setClickable(true);
   // Init state of the filter
   _filter->addItems (settings->value ("workspaceview/mru_list").toStringList ());
 
@@ -111,7 +117,7 @@
   _filter_checkbox->setChecked (filter_state);
   filter_activate (filter_state);
 
-  // Connect signals and slots.
+   // Connect signals and slots.
 
   connect (_filter, SIGNAL (editTextChanged (const QString&)),
            this, SLOT (filter_update (const QString&)));
